mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
* 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>
456 lines
14 KiB
Swift
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}}
|
|
}
|
|
}
|