Files
swift-mirror/test/Sema/diag_constantness_check.swift
Josh Soref 4c77c59269 Spelling sema (#42474)
* spelling: accessibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accessories

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: adjustments

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: all

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: ambiguous

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: arguments

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: assignment

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: associated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: assumes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: auxiliary

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: availability

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: available

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: belongs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: checking

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compatibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: completely

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: completion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: complicated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conformance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: constrained

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: constraint

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: contextual

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: convertible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: couldn't

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declaration

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: defaultable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: dependent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: depending

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: describe

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnostic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnostics

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existential

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: expects

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: explicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: explicitly

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: expression

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: first

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: font

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: forward

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: generation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: generic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: given

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: global

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: guarantee

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: happened

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: hierarchy

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identical

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: immediately

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: implicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indicates

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inferred

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: initialization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: initialize

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: initializer

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: integrity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interpolation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introducing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: involved

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: just

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: like

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: likewise

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: mismatch

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: missing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: more

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessarily

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: noescape

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: nonetheless

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: occurrences

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: operators

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: optional

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: otherwise

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: outside

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overload

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: override

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameters

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: penalize

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: platforms

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: precedence

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: preemptively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: preliminary

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: preserve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: propagate

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: propagated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: qualifier

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: question

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: really

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: received

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: references

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: replaceable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: replacement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: representable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: representative

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requirement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requires

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: resolved

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: rewriting

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: satisfied

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: semantics

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: signature

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: similar

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplest

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplification

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: solver

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: struct

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: structurally

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: success

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: sure

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: symmetric

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: syntactically

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: target

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: that

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: themselves

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: these

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: this

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transform

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transparent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: tread

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: truncation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: type

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unconstructable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: universally

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unknown

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unwrapped

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: versioned

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: visible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: where

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-20 15:12:46 -07:00

456 lines
14 KiB
Swift

// RUN: %target-typecheck-verify-swift -swift-version 5
// Tests for the diagnostics emitted in Sema for checking constantness of
// function arguments annotated to be so. Note that these annotation are
// specific to the new os log overlay and the low-level atomics library.
// The following tests check different types of constants that are accepted
// by the constantness Sema check. It creates helper functions with the
// semantics annotation: "oslog.requires_constant_arguments" which requires that
// all arguments passed to the function are constants. The annotation is meant
// to be used only by the os log overlay. The test helpers use it here only for
// the purpose of testing the functionality.
// Check simple literals.
@_semantics("oslog.requires_constant_arguments")
func constantArgumentFunction<T>(_ constArg: T) {
}
func literalTest(x: Int) {
constantArgumentFunction(1)
constantArgumentFunction("Some string")
constantArgumentFunction(1.9)
constantArgumentFunction(true)
constantArgumentFunction(x)
// expected-error@-1 {{argument must be an integer literal}}
constantArgumentFunction(x + 2)
// expected-error@-1 {{argument must be an integer literal}}
}
@_semantics("oslog.requires_constant_arguments")
func constArgFunctionWithReturn<T>(_ constArg: T) -> T {
return constArg
}
func testConstArgFuncWithReturn(x: Int, str: String) -> Int {
_ = constArgFunctionWithReturn("")
_ = constArgFunctionWithReturn(str)
// expected-error@-1 {{argument must be a string literal}}
constArgFunctionWithReturn(10)
// expected-warning@-1 {{result of call to 'constArgFunctionWithReturn' is unused}}
return constArgFunctionWithReturn(x)
// expected-error@-1 {{argument must be an integer literal}}
}
@_semantics("oslog.requires_constant_arguments")
func constantOptionalArgument(_ constArg: Optional<Int>) {
}
// Correct test cases.
func optionalTest(x: Int) {
constantOptionalArgument(nil)
constantOptionalArgument(0)
constantArgumentFunction(x + 2)
// expected-error@-1 {{argument must be an integer literal}}
}
// Test string interpolation literals. We can only enforce constantness on custom string
// interpolation types. For string types, the constant is a string literal.
struct CustomStringInterpolation : ExpressibleByStringLiteral,
ExpressibleByStringInterpolation {
struct StringInterpolation : StringInterpolationProtocol {
init(literalCapacity: Int, interpolationCount: Int) { }
mutating func appendLiteral(_ x: String) { }
@_semantics("oslog.requires_constant_arguments")
mutating func appendInterpolation(_ x: Int) { }
}
init(stringLiteral value: String) { }
init(stringInterpolation: StringInterpolation) { }
}
@_semantics("oslog.requires_constant_arguments")
func constantStringInterpolation(_ constArg: CustomStringInterpolation) {}
func testStringInterpolationLiteral(x: Int) {
constantStringInterpolation("a string interpolation literal \(x)")
// expected-error@-1 {{argument must be an integer literal}}
constantStringInterpolation("a string interpolation literal \(10)")
}
// Test multiple arguments.
@_semantics("oslog.requires_constant_arguments")
func multipleArguments(_ arg1: Int, _ arg2: Bool, _ arg3: String, _ arg4: Double) {
}
func testMultipleArguments(_ x: String, _ y: Double) {
multipleArguments(56, false, "", 23.3)
multipleArguments(56, false, x, y)
// expected-error@-1 {{argument must be a string literal}}
// expected-error@-2 {{argument must be a floating-point literal}}
}
// Test enum uses.
enum Color {
case red
case blue
case green
case rgb(r: Int, g: Int, b: Int)
}
@_semantics("oslog.requires_constant_arguments")
func enumArgument(_ color: Color) { }
func testEnumArgument(r: Int, c: Color) {
enumArgument(.rgb(r: 12, g: 0, b: 1))
enumArgument(.green)
enumArgument(.rgb(r: r, g: 200, b: 453))
// expected-error@-1 {{argument must be an integer literal}}
enumArgument(c)
// expected-error@-1 {{argument must be a case of enum 'Color'}}
}
// Test type expressions.
@_semantics("oslog.requires_constant_arguments")
func typeArgument<T>(_ t: T.Type) { }
func testTypeArgument<S>(_ t: S.Type) {
typeArgument(Int.self)
typeArgument(S.self)
typeArgument(t)
// expected-error@-1 {{argument must be a <Type>.self}}
}
// Test constant evaluable function calls.
@_semantics("constant_evaluable")
func constantEval(_ x: Int, _ y: Bool) -> Int { x + 100 }
func testConstantEvalArgument(x: Int) {
constantArgumentFunction(constantEval(90, true))
constantArgumentFunction(constantEval(constantEval(500, true), false))
constantArgumentFunction(constantEval(x, true))
// expected-error@-1 {{argument must be an integer literal}}
}
// Test constant evaluable function calls with default arguments.
@_semantics("constant_evaluable")
func constantEvalAdvanced(_ x: () -> Int, _ y: Bool = true, z: String) { }
func testConstantEvalAdvanced(arg: Int) {
constantArgumentFunction(constantEvalAdvanced({ arg }, z: ""))
}
// Test constant evaluable methods.
struct E {
// expected-note@-1 {{'E' declared here}}
func constantEvalMethod1() -> E { return self }
@_semantics("constant_evaluable")
func constantEvalMethod2() -> E { return self }
@_semantics("constant_evaluable")
static func constantEvalMethod3(x: Bool) -> E { return E() }
@_semantics("constant_evaluable")
static func constantEvalMethod4() -> E { return E() }
}
@_semantics("oslog.requires_constant_arguments")
func functionNeedingConstE(_ x: E) { }
func testConstantEvalMethod(b: Bool) {
functionNeedingConstE(E().constantEvalMethod1())
// expected-error@-1 {{argument must be a static method or property of 'E'}}
functionNeedingConstE(E().constantEvalMethod2())
functionNeedingConstE(.constantEvalMethod3(x: true))
functionNeedingConstE(.constantEvalMethod3(x: b))
// expected-error@-1 {{argument must be a bool literal}}
functionNeedingConstE(.constantEvalMethod4())
}
// Test functions with autoclosures.
@_semantics("oslog.requires_constant_arguments")
func autoClosureArgument(_ number: @autoclosure @escaping () -> Int) { }
func testAutoClosure(_ number: Int) {
autoClosureArgument(number)
}
@_semantics("constant_evaluable")
func constEvalWithAutoClosure(_ number: @autoclosure @escaping () -> Int) -> Int {
return 0
}
func testConstantEvalAutoClosure(_ number: Int) {
constantArgumentFunction(constEvalWithAutoClosure(number))
}
// Test nested use of constant parameter.
@_semantics("oslog.requires_constant_arguments")
func testConstantArgumentRequirementPropagation(constParam: Int) {
constantArgumentFunction(constParam)
}
// Test nested use of constant parameter in constant evaluable function.
@_semantics("oslog.requires_constant_arguments")
func testConstantArgumentWithConstEval(constParam: Int) {
constantArgumentFunction(constantEval(constParam, true))
}
// Test parital-apply of constantArgumentFunction.
@_semantics("oslog.requires_constant_arguments")
func constArg2(_ x: Int) -> Int { x }
// This is not an error.
func testPartialApply() -> ((Int) -> Int) {
return constArg2
}
@_semantics("oslog.requires_constant_arguments")
func constArg3(_ x: (Int) -> Int) -> Int { x(0) }
@_semantics("constant_evaluable")
func intIdentity(_ x: Int) -> Int { x }
func testPartialApply2() -> Int {
return constArg3(intIdentity)
// expected-error@-1 {{argument must be a closure}}
}
// Test struct and class constructions. Structs whose initializers are marked as
// constant_evaluable are considered as constants.
struct AStruct {
var i: Int
}
struct BStruct {
var i: Int
@_semantics("constant_evaluable")
init(_ value: Int) {
i = value
}
}
class CClass {
var str: String
init() {
str = ""
}
}
func testStructAndClasses(arg: Int) {
constantArgumentFunction(AStruct(i: 9))
// expected-error@-1 {{argument must be a static method or property of 'AStruct'}}
constantArgumentFunction(BStruct(340))
constantArgumentFunction(CClass())
// expected-error@-1 {{argument must be a static method or property of 'CClass'}}
}
// Test "requires_constant" annotation on protocol requirements.
protocol Proto {
@_semantics("oslog.requires_constant_arguments")
func method(arg1: Int, arg2: Bool)
}
struct SConf : Proto {
func method(arg1: Int, arg2: Bool) { }
}
func testProtocolMethods<T: Proto>(b: Bool, p: T, p2: Proto, s: SConf) {
p.method(arg1: 6, arg2: true)
p.method(arg1: 6, arg2: b)
// expected-error@-1 {{argument must be a bool literal}}
p2.method(arg1: 6, arg2: b)
// expected-error@-1 {{argument must be a bool literal}}
// Note that even though 's' conforms to Proto, since its method is not
// annotated as requiring constant arg2, there will be no error here.
s.method(arg1: 6, arg2: b)
}
// Check requires annotation on a class method.
class ClassD {
@_semantics("oslog.requires_constant_arguments")
func method(_ arg1: Int, _ arg2: Bool)
}
func testClassMethod(d: ClassD, b: Bool) {
d.method(10, true)
d.method(10, b)
// expected-error@-1 {{argument must be a bool literal}}
}
// Test that the check is resilient to errors in the semantics attribute.
@_semantics("oslog.requires_constant_")
func funcWithWrongSemantics(x: Int) {}
func testFunctionWithWrongSemantics(x: Int) {
funcWithWrongSemantics(x: x)
}
// Test that the check is resilient to other type errors.
func testOtherTypeErrors() {
constantArgumentFunction(x)
// expected-error@-1 {{cannot find 'x' in scope}}
constantArgumentFunction(10 as String)
// expected-error@-1 {{cannot convert value of type 'Int' to type 'String' in coercion}}
}
// Test constantness of the ordering used in the atomic operations. The atomic
// operations that requires a constant ordering are required to use the
// semantics annotation "atomics.requires_constant_orderings".
internal struct AtomicLoadOrdering {
@_semantics("constant_evaluable")
internal static var acquiring: Self { Self() }
@_semantics("constant_evaluable")
internal static var sequentiallyConsistent: Self { Self() }
}
internal struct UnsafeAtomicIntStub {
@_semantics("atomics.requires_constant_orderings")
internal func load(
ordering: AtomicLoadOrdering = .sequentiallyConsistent
) -> Int {
return 0
}
}
func testAtomicOrderingConstantness(
atomicInt: UnsafeAtomicIntStub,
myOrder: AtomicLoadOrdering
) {
_ = atomicInt.load()
_ = atomicInt.load(ordering: .acquiring)
_ = atomicInt.load(ordering: .sequentiallyConsistent)
_ = atomicInt.load(ordering: myOrder)
// expected-error@-1 {{ordering argument must be a static method or property of 'AtomicLoadOrdering'}}
}
// Test that the check can handle ranges
@_semantics("oslog.requires_constant_arguments")
func constantRange(x: Range<Int>) {}
@_semantics("oslog.requires_constant_arguments")
func constantClosedRange(x: ClosedRange<Int>) {}
func testConstantRange(x: Int) {
constantRange(x: 0..<5)
constantRange(x: 0..<x)
// expected-error@-1 {{argument must be an integer literal}}
constantClosedRange(x: 0...10)
constantClosedRange(x: x...10)
// expected-error@-1 {{argument must be an integer literal}}
}
struct ConstructorTest {
@_semantics("oslog.requires_constant_arguments")
init(x: Int) { }
@_semantics("oslog.requires_constant_arguments")
init(_ x: Int) { }
}
func testConstructorAnnotation(x: Int) {
let _ = ConstructorTest(x: 10)
let _ = ConstructorTest(x: x)
// expected-error@-1 {{argument must be an integer literal}}
let _ = ConstructorTest(10)
let _ = ConstructorTest(x)
// expected-error@-1 {{argument must be an integer literal}}
}
// Test closure expressions
func funcAcceptingClosure<T>(_ x: () -> T) -> T {
return x()
}
func normalFunction() {}
@_semantics("oslog.requires_constant_arguments")
func constantArgumentFunctionReturningIntCollection(_ constArg: Int) -> Array<Int> {
return [constArg, constArg, constArg]
}
@_semantics("oslog.requires_constant_arguments")
func constantArgumentFunctionReturningInt(_ constArg: Int) -> Int {
return constArg
}
func testCallsWithinClosures(s: String, x: Int) {
funcAcceptingClosure {
constantArgumentFunction(s)
// expected-error@-1 {{argument must be a string literal}}
}
funcAcceptingClosure {
constantArgumentFunction(s)
// expected-error@-1 {{argument must be a string literal}}
constantArgumentFunction(s)
// expected-error@-1 {{argument must be a string literal}}
}
funcAcceptingClosure {
funcAcceptingClosure {
constantArgumentFunction(s)
// expected-error@-1 {{argument must be a string literal}}
}
}
funcAcceptingClosure {
normalFunction()
funcAcceptingClosure {
constantArgumentFunction(s)
// expected-error@-1 {{argument must be a string literal}}
}
}
let _ =
funcAcceptingClosure {
constantArgumentFunctionReturningIntCollection(x)
// expected-error@-1 {{argument must be an integer literal}}
}
.filter { $0 > 0 }
.map { $0 + 1 }
let _ =
funcAcceptingClosure {
constantArgumentFunctionReturningInt(x)
// expected-error@-1 {{argument must be an integer literal}}
} + 10 * x
let _ = { constantArgumentFunctionReturningIntCollection(x) }
// expected-error@-1 {{argument must be an integer literal}}
funcAcceptingClosure {
constantArgumentFunction(1)
constantArgumentFunction("string literal")
constantArgumentFunction("string with a single interpolation \(x)")
}
}
@resultBuilder
struct MyArrayBuilder {
typealias Component = [Int]
typealias Expression = Int
static func buildExpression(_ element: Expression) -> Component {
return [element]
}
static func buildBlock(_ components: Component...) -> Component {
return Array(components.joined())
}
}
struct MyArray {
public init(@MyArrayBuilder arr: () -> [Int]) {}
}
func testResultBuilder(x: Int, y: Int) -> MyArray {
let _: MyArray = MyArray {
constantArgumentFunctionReturningInt(x)
// expected-error@-1 {{argument must be an integer literal}}
constantArgumentFunctionReturningInt(y)
// expected-error@-1 {{argument must be an integer literal}}
}
let _: MyArray = MyArray {
constantArgumentFunctionReturningInt(x)
// expected-error@-1 {{argument must be an integer literal}}
}
}