Files
swift-mirror/test/Sema/property_wrapper_parameter_invalid.swift
Allan Shortlidge 7e6e8ed7b5 Sema: Fully check the availability of wrappedValue.
Call `checkDeclarationAvailability()`, instead of just diagnosing
unavailability.
2024-10-25 16:50:20 -07:00

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()
}
}