mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
302 lines
13 KiB
Swift
302 lines
13 KiB
Swift
// RUN: %target-typecheck-verify-swift -swift-version 5 -package-name myPkg
|
|
|
|
@propertyWrapper
|
|
struct NonMutatingWrapper<T> {
|
|
var wrappedValue: T {
|
|
get { fatalError() }
|
|
nonmutating set { fatalError() }
|
|
}
|
|
|
|
init(wrappedValue: T) { fatalError() }
|
|
}
|
|
|
|
@propertyWrapper
|
|
struct MutatingWrapper<T> {
|
|
var wrappedValue: T {
|
|
mutating get { fatalError() }
|
|
}
|
|
|
|
init(wrappedValue: T) { fatalError() }
|
|
}
|
|
|
|
// expected-error@+1 {{property wrapper applied to parameter must have a nonmutating 'wrappedValue' getter}}
|
|
func testMutatingGetter(@MutatingWrapper value: Int) {}
|
|
|
|
// expected-error@+1 {{property wrapper applied to parameter must have a nonmutating 'wrappedValue' getter}}
|
|
func testComposedMutating(@MutatingWrapper @NonMutatingWrapper value: Int) {}
|
|
|
|
// okay
|
|
func testComposedNonMutating(@NonMutatingWrapper @MutatingWrapper value: Int) {}
|
|
|
|
@propertyWrapper
|
|
struct NoProjection<T> {
|
|
var wrappedValue: T
|
|
}
|
|
|
|
// expected-note@+1 {{property wrapper type 'NoProjection<String>' does not support initialization from a projected value}}
|
|
func takesNoProjectionWrapper(@NoProjection value: String) {}
|
|
|
|
// expected-note@+1 {{property wrapper type 'NoProjection<String>' does not support initialization from a projected value}}
|
|
func takesNoProjectionWrapperWithDefault(_: Int? = nil, @NoProjection value: String) {}
|
|
|
|
// expected-note@+1 {{property wrapper type 'NoProjection<String>' does not support initialization from a projected value}}
|
|
func takesNoProjectionWrapperWithVariadic(_: Int..., @NoProjection value: String) {}
|
|
|
|
func testNoProjection(message: String) {
|
|
takesNoProjectionWrapper(value: message) // okay
|
|
|
|
// expected-error@+1 {{cannot use property wrapper projection argument}}
|
|
takesNoProjectionWrapper($value: message)
|
|
|
|
// expected-error@+1 {{cannot use property wrapper projection argument}}
|
|
takesNoProjectionWrapperWithDefault($value: message)
|
|
|
|
// expected-error@+1 {{cannot use property wrapper projection argument}}
|
|
takesNoProjectionWrapperWithVariadic(1, 2, 3, $value: message)
|
|
|
|
// expected-error@+2 {{cannot use property wrapper projection parameter}}
|
|
// expected-note@+1 {{property wrapper type 'NoProjection<Int>' does not support initialization from a projected value}}
|
|
let _: (NoProjection<Int>) -> Int = { $value in
|
|
return value
|
|
}
|
|
}
|
|
|
|
struct Projection<T> {
|
|
var value: T
|
|
}
|
|
|
|
// expected-note@+2 {{generic struct 'Wrapper' is not '@usableFromInline' or public}}
|
|
@propertyWrapper
|
|
struct Wrapper<T> { // expected-note 3 {{type declared here}}
|
|
// expected-note@+1 {{initializer 'init(wrappedValue:)' is not '@usableFromInline' or public}}
|
|
init(wrappedValue: T) {
|
|
self.wrappedValue = wrappedValue
|
|
}
|
|
|
|
init(projectedValue: Projection<T>) {
|
|
self.wrappedValue = projectedValue.value
|
|
}
|
|
|
|
// expected-note@+1 {{property 'wrappedValue' is not '@usableFromInline' or public}}
|
|
var wrappedValue: T
|
|
var projectedValue: Projection<T> { Projection(value: wrappedValue) }
|
|
}
|
|
|
|
// expected-note@+2 {{property wrapper has arguments in the wrapper attribute}}
|
|
// expected-note@+1 {{in call to function 'hasWrapperAttributeArg(value:)'}}
|
|
func hasWrapperAttributeArg<T>(@Wrapper() value: T) {}
|
|
|
|
func testWrapperAttributeArg(projection: Projection<Int>) {
|
|
hasWrapperAttributeArg(value: projection.value)
|
|
|
|
// expected-error@+2 {{cannot use property wrapper projection argument}}
|
|
// expected-error@+1 {{generic parameter 'T' could not be inferred}}
|
|
hasWrapperAttributeArg($value: projection)
|
|
}
|
|
|
|
struct S {
|
|
// expected-error@+1 {{property wrapper attribute on parameter not yet supported on subscript}}
|
|
subscript(@Wrapper position: Int) -> Int { 0 }
|
|
}
|
|
|
|
func testInvalidArgLabel(projection: Projection<Int>) {
|
|
// expected-note@+1 2 {{parameter 'argLabel' does not have an attached property wrapper}}
|
|
func noWrappers(argLabel: Int) {}
|
|
|
|
// expected-error@+1 {{cannot use property wrapper projection argument}}
|
|
let ref = noWrappers($argLabel:)
|
|
|
|
// expected-error@+1 {{cannot use property wrapper projection argument}}
|
|
noWrappers($argLabel: 10)
|
|
|
|
func takesWrapper(@Wrapper argLabel: Int) {}
|
|
|
|
// expected-error@+1 {{cannot convert value of type 'Projection<Int>' to expected argument type 'Int'}}
|
|
takesWrapper(argLabel: projection)
|
|
}
|
|
|
|
protocol P {
|
|
// expected-error@+1 {{parameter 'arg' declared inside a protocol cannot have a wrapper}}
|
|
func requirement(@Wrapper arg: Int)
|
|
}
|
|
|
|
enum E {
|
|
// expected-error@+1 {{expected parameter name followed by ':'}}
|
|
case one(@Wrapper value: Int)
|
|
}
|
|
|
|
// expected-error@+1 {{function cannot be declared public because its parameter uses an internal API wrapper type}}
|
|
public func f1(@Wrapper value: Int) {}
|
|
|
|
// expected-error@+4 {{property 'wrappedValue' is internal and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+3 {{generic struct 'Wrapper' is internal and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+2 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}}
|
|
// expected-error@+1 {{initializer 'init(wrappedValue:)' is internal and cannot be referenced from an '@inlinable' function}}
|
|
@inlinable func f2(@Wrapper value: Int) {}
|
|
|
|
// expected-error@+1 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}}
|
|
@usableFromInline func f3(@Wrapper value: Int) {}
|
|
|
|
@available(*, unavailable)
|
|
@propertyWrapper
|
|
struct UnavailableWrapper<T> { // expected-note {{'UnavailableWrapper' has been explicitly marked unavailable here}}
|
|
var wrappedValue: T
|
|
}
|
|
|
|
// expected-error@+1 {{'UnavailableWrapper' is unavailable}}
|
|
func testUnavailableWrapper(@UnavailableWrapper value: Int) {}
|
|
|
|
@propertyWrapper
|
|
public struct PublicWrapper<T> {
|
|
public init(wrappedValue: T) { fatalError() }
|
|
public init(projectedValue: PublicWrapper<T>) { fatalError() }
|
|
public var wrappedValue: T
|
|
public var projectedValue: PublicWrapper<T> { self }
|
|
}
|
|
|
|
// expected-note@+2 2 {{generic struct 'PackageWrapper' is not '@usableFromInline' or public}}
|
|
@propertyWrapper
|
|
package struct PackageWrapper<T> { // expected-note 3 {{type declared here}}
|
|
// expected-note@+1 2 {{property 'wrappedValue' is not '@usableFromInline' or public}}
|
|
package var wrappedValue: T
|
|
|
|
// expected-note@+1 2 {{initializer 'init(wrappedValue:)' is not '@usableFromInline' or public}}
|
|
package init(wrappedValue: T) { self.wrappedValue = wrappedValue }
|
|
}
|
|
|
|
// expected-note@+2 2 {{generic struct 'InternalWrapper' is not '@usableFromInline' or public}}
|
|
@propertyWrapper
|
|
struct InternalWrapper<T> { // expected-note 3 {{type declared here}}
|
|
// expected-note@+1 2 {{property 'wrappedValue' is not '@usableFromInline' or public}}
|
|
var wrappedValue: T
|
|
|
|
// expected-note@+1 2 {{initializer 'init(wrappedValue:)' is not '@usableFromInline' or public}}
|
|
init(wrappedValue: T) { self.wrappedValue = wrappedValue }
|
|
}
|
|
|
|
func testWrapperStorageMutability(@InternalWrapper value: Int) {
|
|
_ = _value
|
|
// expected-error@+1 {{cannot assign to value: '_value' is immutable}}
|
|
_value = InternalWrapper(wrappedValue: 10)
|
|
}
|
|
|
|
// expected-error@+1 {{function cannot be declared public because its parameter uses an internal API wrapper type}}
|
|
public func testComposition1(@PublicWrapper @InternalWrapper value: Int) {}
|
|
|
|
// Okay because `InternalWrapper` is implementation-detail.
|
|
public func testComposition2(@InternalWrapper @PublicWrapper value: Int) {}
|
|
|
|
// expected-error@+1 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}}
|
|
@usableFromInline func testComposition3(@PublicWrapper @InternalWrapper value: Int) {}
|
|
|
|
// Okay because `InternalWrapper` is implementation-detail.
|
|
@usableFromInline func testComposition4(@InternalWrapper @PublicWrapper value: Int) {}
|
|
|
|
// expected-error@+1 {{function cannot be declared public because its parameter uses a package API wrapper type}}
|
|
public func testComposition1pkg(@PublicWrapper @PackageWrapper value: Int) {}
|
|
|
|
// Okay because `PackageWrapper` is implementation-detail.
|
|
public func testComposition2pkg(@PackageWrapper @PublicWrapper value: Int) {}
|
|
|
|
// expected-error@+1 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}}
|
|
@usableFromInline func testComposition3pkg(@PublicWrapper @PackageWrapper value: Int) {}
|
|
|
|
// Okay because `PackageWrapper` is implementation-detail.
|
|
@usableFromInline func testComposition4pkg(@PackageWrapper @PublicWrapper value: Int) {}
|
|
|
|
// expected-error@+4 {{property 'wrappedValue' is internal and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+3 {{generic struct 'InternalWrapper' is internal and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+2 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}}
|
|
// expected-error@+1 {{initializer 'init(wrappedValue:)' is internal and cannot be referenced from an '@inlinable' function}}
|
|
@inlinable func testComposition5(@PublicWrapper @InternalWrapper value: Int) {}
|
|
|
|
// expected-error@+3 {{property 'wrappedValue' is internal and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+2 {{generic struct 'InternalWrapper' is internal and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+1 {{initializer 'init(wrappedValue:)' is internal and cannot be referenced from an '@inlinable' function}}
|
|
@inlinable func testComposition6(@InternalWrapper @PublicWrapper value: Int) {}
|
|
|
|
// expected-error@+4 {{property 'wrappedValue' is package and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+3 {{generic struct 'PackageWrapper' is package and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+2 {{the parameter API wrapper of a '@usableFromInline' function must be '@usableFromInline' or public}}
|
|
// expected-error@+1 {{initializer 'init(wrappedValue:)' is package and cannot be referenced from an '@inlinable' function}}
|
|
@inlinable func testComposition5pkg(@PublicWrapper @PackageWrapper value: Int) {}
|
|
|
|
// expected-error@+3 {{property 'wrappedValue' is package and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+2 {{generic struct 'PackageWrapper' is package and cannot be referenced from an '@inlinable' function}}
|
|
// expected-error@+1 {{initializer 'init(wrappedValue:)' is package and cannot be referenced from an '@inlinable' function}}
|
|
@inlinable func testComposition6pkg(@PackageWrapper @PublicWrapper value: Int) {}
|
|
|
|
protocol Q {
|
|
associatedtype A
|
|
}
|
|
|
|
// expected-note@+1 {{where 'T' = 'Int'}}
|
|
func takesClosure<T: Q>(type: T.Type, _ closure: (T.A) -> Void) {}
|
|
|
|
func testMissingWrapperType() {
|
|
// expected-error@+1 {{global function 'takesClosure(type:_:)' requires that 'Int' conform to 'Q'}}
|
|
takesClosure(type: Int.self) { $value in
|
|
return
|
|
}
|
|
|
|
struct S: Q {
|
|
typealias A = (Int, Int)
|
|
}
|
|
|
|
// expected-error@+1 {{inferred projection type 'S.A' (aka '(Int, Int)') is not a property wrapper}}
|
|
takesClosure(type: S.self) { $value in
|
|
return
|
|
}
|
|
}
|
|
|
|
@propertyWrapper
|
|
struct OptionalWrapper<Value> { // expected-note {{'Value' declared as parameter to type 'OptionalWrapper'}}
|
|
var wrappedValue: Value?
|
|
var projectedValue: Self { self }
|
|
init(wrappedValue: Value?) { self.wrappedValue = wrappedValue }
|
|
init(projectedValue: Self) { self = projectedValue }
|
|
}
|
|
|
|
// expected-error@+2 {{generic parameter 'Value' could not be inferred}} expected-note@+2 {{}}
|
|
// expected-error@+1 {{property type 'Int' does not match 'wrappedValue' type 'Value?'}}
|
|
func testWrappedValueMismatch(@OptionalWrapper value: Int) {}
|
|
|
|
@propertyWrapper
|
|
struct ProjectionWrapper<Value> {
|
|
var wrappedValue: Value
|
|
var projectedValue: Self { self }
|
|
init(projectedValue: Self) { self = projectedValue }
|
|
}
|
|
|
|
func testInvalidWrapperInference() {
|
|
struct S<V> {
|
|
static func test(_ keyPath: KeyPath<V, String>) {} // expected-note 2 {{'test' declared here}}
|
|
}
|
|
|
|
// expected-error@+1 {{trailing closure passed to parameter of type 'KeyPath<Int, String>' that does not accept a closure}}
|
|
S<Int>.test { $value in }
|
|
// expected-error@+1 {{closure passed to parameter of type 'KeyPath<Int, String>' that does not accept a closure}}
|
|
S<Int>.test({ $value in })
|
|
|
|
func testGenericClosure<T>(_ closure: T) {}
|
|
// expected-error@+1 {{cannot infer type of closure parameter '$value' without a type annotation}}
|
|
testGenericClosure { $value in }
|
|
testGenericClosure { ($value: ProjectionWrapper<Int>) in } // okay
|
|
|
|
func testExtraParameter(_ closure: () -> Void) {}
|
|
// expected-error@+1 {{contextual closure type '() -> Void' expects 0 arguments, but 1 was used in closure body}}
|
|
testExtraParameter { $value in }
|
|
}
|
|
|
|
// rdar://116522161 - failed to produce a diagnostic on invalid projection use
|
|
func testInvalidProjectionInAmbiguousContext() {
|
|
func test<T>(_: [T], _: (T) -> Void) {}
|
|
|
|
func ambiguous() -> Int { 42 }
|
|
func ambiguous() -> String { "" }
|
|
|
|
test([42]) { $v in // expected-error {{inferred projection type 'Int' is not a property wrapper}}
|
|
ambiguous()
|
|
}
|
|
}
|