// RUN: %target-typecheck-verify-swift \ // RUN: -enable-experimental-feature LifetimeDependence \ // RUN: -enable-experimental-feature SuppressedAssociatedTypes // REQUIRES: swift_feature_LifetimeDependence // REQUIRES: swift_feature_SuppressedAssociatedTypes // expected-note@+1 {{'T' has '~Copyable' constraint preventing implicit 'Copyable' conformance}} struct AttemptImplicitConditionalConformance: ~Copyable { var t: T // expected-error {{stored property 't' of 'Copyable'-conforming generic struct 'AttemptImplicitConditionalConformance' has non-Copyable type 'T'}} } extension AttemptImplicitConditionalConformance: Copyable {} // expected-error@-1 {{generic struct 'AttemptImplicitConditionalConformance' required to be 'Copyable' but is marked with '~Copyable'}} // expected-error@-2 {{must explicitly state whether 'T' is required to conform to 'Copyable'}} enum Hello: ~Escapable & ~Copyable {} extension Hello: Escapable {} // expected-error {{generic enum 'Hello' required to be 'Escapable' but is marked with '~Escapable'}} // expected-error@-1 {{must explicitly state whether 'T' is required to conform to 'Copyable'}} // expected-error@-2 {{must explicitly state whether 'T' is required to conform to 'Escapable'}} extension Hello: Copyable {} // expected-error {{generic enum 'Hello' required to be 'Copyable' but is marked with '~Copyable'}} // expected-error@-1 {{must explicitly state whether 'T' is required to conform to 'Copyable'}} // expected-error@-2 {{must explicitly state whether 'T' is required to conform to 'Escapable'}} enum HelloExplicitlyFixed: Escapable, Copyable {} struct NoInverseBecauseNoDefault: ~Copyable {} extension NoInverseBecauseNoDefault: Copyable where T: Copyable, T: ~Escapable {} // Check support for explicit conditional conformance public struct ExplicitCond: ~Copyable {} extension ExplicitCond: Copyable where T: Copyable {} // expected-note@-1 {{requirement from conditional conformance}} // expected-note@-2 {{requirement from conditional conformance of 'ExplicitCondAlias' (aka 'ExplicitCond') to 'Copyable'}} public typealias ExplicitCondAlias = ExplicitCond where T: ~Copyable public typealias AlwaysCopyable = ExplicitCond func checkCopyable(_ t: T) {} // expected-note {{'where T: Copyable' is implicit here}} func test( _ a1: ExplicitCond, _ b1: borrowing ExplicitCond, _ a2: ExplicitCondAlias, _ b2: borrowing ExplicitCondAlias ) { checkCopyable(a1) checkCopyable(b1) // expected-error {{global function 'checkCopyable' requires that 'NC' conform to 'Copyable'}} checkCopyable(a2) checkCopyable(b2) // expected-error {{global function 'checkCopyable' requires that 'NC' conform to 'Copyable'}} } func checkAliases(_ a: AlwaysCopyable, _ b: AlwaysCopyable) { // expected-error@-1 {{'NC' required to be 'Copyable' but is marked with '~Copyable'}} checkCopyable(a) checkCopyable(b) } protocol NeedsCopyable {} // expected-note@-1 {{type 'TryInferCopyable' does not conform to inherited protocol 'Copyable'}} struct TryInferCopyable: ~Copyable, NeedsCopyable {} // expected-error@-1 {{type 'TryInferCopyable' does not conform to protocol 'Copyable'}} protocol Removed: ~Copyable { func requiresCopyableSelf(_ t: AlwaysCopyable) // expected-error@-1 {{type 'Self' does not conform to protocol 'Copyable'}} } protocol Plain { associatedtype T: ~Copyable func requiresCopyableSelf(_ t: AlwaysCopyable) func requiresCopyableT(_ t: AlwaysCopyable) // expected-error@-1 {{type 'Self.T' does not conform to protocol 'Copyable'}} } protocol RemovedAgain where Self: ~Copyable { func requiresCopyableSelf(_ t: AlwaysCopyable) // expected-error {{type 'Self' does not conform to protocol 'Copyable'}} } struct StructContainment : Copyable { var storage: Maybe // expected-error@-1 {{stored property 'storage' of 'Copyable'-conforming generic struct 'StructContainment' has non-Copyable type 'Maybe'}} } enum EnumContainment : Copyable { // expected-note@-1 {{'T' has '~Copyable' constraint preventing implicit 'Copyable' conformance}} case some(T) // expected-error {{associated value 'some' of 'Copyable'-conforming generic enum 'EnumContainment' has non-Copyable type 'T'}} case other(Int) case none } class ClassContainment { var storage: T init(_ t: consuming T) { storage = t checkCopyable(t) // expected-error {{global function 'checkCopyable' requires that 'T' conform to 'Copyable'}} } deinit {} } struct ConditionalContainment: ~Copyable { var x: T var y: NC // expected-error {{stored property 'y' of 'Copyable'-conforming generic struct 'ConditionalContainment' has non-Copyable type 'NC'}} } extension ConditionalContainment: Copyable where T: Copyable {} func chk(_ T: RequireCopyable>) {} func chk(_ t: ConditionalContainment) {} // expected-error@-1 {{parameter of noncopyable type 'ConditionalContainment' must specify ownership}} // expected-note@-2 3{{add}} /// ---------------- // expected-note@+2 3{{add}} // expected-error@+1 {{parameter of noncopyable type 'some Escapable & ~Copyable' must specify ownership}} func dogDays(_ t: some Escapable & ~Copyable) {} /// ---------------- struct AlwaysCopyableDeinit : Copyable { let nc: NC // expected-error {{stored property 'nc' of 'Copyable'-conforming generic struct 'AlwaysCopyableDeinit' has non-Copyable type 'NC'}} deinit {} // expected-error {{deinitializer cannot be declared in generic struct 'AlwaysCopyableDeinit' that conforms to 'Copyable'}} } struct SometimesCopyableDeinit : ~Copyable { deinit {} // expected-error {{deinitializer cannot be declared in generic struct 'SometimesCopyableDeinit' that conforms to 'Copyable'}} } extension SometimesCopyableDeinit: Copyable where T: Copyable {} struct NeverCopyableDeinit: ~Copyable { deinit {} } protocol Test: ~Copyable { init?() } struct NoncopyableAndSendable: ~Copyable, Sendable {} /// --------------- // expected-note@+1 {{generic enum 'Maybe' has '~Copyable' constraint preventing 'Copyable' conformance}} enum Maybe: ~Copyable { case just(Wrapped) case none deinit {} // expected-error {{deinitializer cannot be declared in generic enum 'Maybe' that conforms to 'Copyable'}} } extension Maybe: Copyable where Wrapped: Copyable {} // expected-note@+4{{requirement specified as 'NC' : 'Copyable'}} // expected-note@+3{{requirement from conditional conformance of 'Maybe' to 'Copyable'}} // expected-note@+2{{requirement specified as 'Wrapped' : 'Copyable'}} // expected-note@+1{{requirement from conditional conformance of 'Maybe' to 'Copyable'}} struct RequireCopyable { // expected-note@-1 {{consider adding '~Copyable' to generic struct 'RequireCopyable'}}{{27-27=: ~Copyable }} deinit {} // expected-error {{deinitializer cannot be declared in generic struct 'RequireCopyable' that conforms to 'Copyable'}} } struct NC: ~Copyable { // expected-note@-1 3{{struct 'NC' has '~Copyable' constraint preventing 'Copyable' conformance}} deinit {} } typealias ok1 = RequireCopyable typealias ok2 = RequireCopyable> typealias err1 = RequireCopyable> // expected-error@-1{{type 'NC' does not conform to protocol 'Copyable'}} // expected-error@-2{{'RequireCopyable' requires that 'NC' conform to 'Copyable'}} typealias err2 = RequireCopyable // expected-error@-1{{type 'NC' does not conform to protocol 'Copyable'}} extension Maybe where Wrapped: ~Copyable { func check1(_ t: RequireCopyable) {} // expected-error@-1 {{type 'Wrapped' does not conform to protocol 'Copyable'}} // expected-error@-2 {{'RequireCopyable' requires that 'Wrapped' conform to 'Copyable'}} } extension Maybe { func check2(_ t: RequireCopyable) {} } /// MARK: tests that we diagnose ~Copyable that became invalid because it's required to be copyable struct Silly: ~Copyable, Copyable {} // expected-error {{struct 'Silly' required to be 'Copyable' but is marked with '~Copyable'}} enum Sally: Copyable, ~Copyable, NeedsCopyable {} // expected-error {{enum 'Sally' required to be 'Copyable' but is marked with '~Copyable'}} class NiceTry: ~Copyable, Copyable {} // expected-error {{classes cannot be '~Copyable'}} struct Extendo: ~Copyable {} extension Extendo: Copyable, ~Copyable {} // expected-error {{cannot suppress 'Copyable' in extension}} // expected-error@-1 {{struct 'Extendo' required to be 'Copyable' but is marked with '~Copyable'}} enum EnumExtendo {} extension EnumExtendo: ~Copyable {} // expected-error {{cannot suppress 'Copyable' in extension}} extension NeedsCopyable where Self: ~Copyable {} // expected-error@-1 {{'Self' required to be 'Copyable' but is marked with '~Copyable'}} protocol NoCopyP: ~Copyable {} func needsCopyable(_ t: T) {} // expected-note 2{{'where T: Copyable' is implicit here}} func noCopyable(_ t: borrowing some ~Copyable) {} func noCopyableAndP(_ t: borrowing some NoCopyP & ~Copyable) {} func openingExistentials(_ a: borrowing any NoCopyP & ~Copyable, _ b: any NoCopyP, _ nc: borrowing any ~Copyable) { needsCopyable(a) // expected-error {{global function 'needsCopyable' requires that 'T' conform to 'Copyable'}} noCopyable(a) noCopyableAndP(a) needsCopyable(b) noCopyable(b) noCopyableAndP(b) needsCopyable(nc) // expected-error {{global function 'needsCopyable' requires that 'T' conform to 'Copyable'}} noCopyable(nc) noCopyableAndP(nc) // expected-error {{global function 'noCopyableAndP' requires that 'some NoCopyP & ~Copyable' conform to 'NoCopyP'}} } func project(_ base: CurValue) { } func testSpecial(_ a: Any) { _openExistential(a, do: project) } /// MARK: non-Escapable types func requireEscape(_ t: borrowing T) {} // expected-note {{generic parameters are always considered '@escaping'}} // expected-note@-1 4{{'where T: Escapable' is implicit here}} func genericNoEscape(_ t: borrowing T) {} // expected-note {{generic parameters are always considered '@escaping'}} // expected-note@-1 2{{'where T: Copyable' is implicit here}} func genericNoEscapeOrCopy(_ t: borrowing T) {} func checkFunctions(_ f: @autoclosure () -> Int) { requireEscape(f) // expected-error {{converting non-escaping parameter 'f' to generic parameter 'T' may allow it to escape}} // FIXME: rdar://119410346 (nonescaping function is not permitted as arg to ~Escapable generic function) genericNoEscape(f) // expected-error {{converting non-escaping parameter 'f' to generic parameter 'T' may allow it to escape}} } struct BuggerView: ~Escapable, Copyable {} struct MutableBuggerView: ~Copyable, ~Escapable {} @lifetime(mutRef: copy mutRef) func checkNominals(_ mutRef: inout MutableBuggerView, _ ref: BuggerView, _ intMutRef: borrowing MutableBuggerView, _ intRef: BuggerView) { genericNoEscape(mutRef) // expected-error {{global function 'genericNoEscape' requires that 'MutableBuggerView' conform to 'Copyable'}} genericNoEscape(ref) genericNoEscape(intMutRef) // expected-error {{global function 'genericNoEscape' requires that 'MutableBuggerView' conform to 'Copyable'}} genericNoEscape(intRef) genericNoEscapeOrCopy(mutRef) genericNoEscapeOrCopy(ref) genericNoEscapeOrCopy(intMutRef) genericNoEscapeOrCopy(intRef) requireEscape(mutRef) // expected-error {{global function 'requireEscape' requires that 'MutableBuggerView' conform to 'Escapable'}} requireEscape(ref) // expected-error {{global function 'requireEscape' requires that 'BuggerView' conform to 'Escapable'}} requireEscape(intMutRef) // expected-error {{global function 'requireEscape' requires that 'MutableBuggerView' conform to 'Escapable'}} requireEscape(intRef) // expected-error {{global function 'requireEscape' requires that 'BuggerView' conform to 'Escapable'}} } struct NonescapingType: ~Escapable {} struct NonescapeDoesNotAllowNoncopyable: ~Escapable { // expected-note {{consider adding '~Copyable' to struct 'NonescapeDoesNotAllowNoncopyable'}} let x: NC // expected-error {{stored property 'x' of 'Copyable'-conforming struct 'NonescapeDoesNotAllowNoncopyable' has non-Copyable type 'NC'}} init(_ x: borrowing NC) { self.x = x } } enum MaybeEscapes: ~Escapable { // expected-note {{generic enum 'MaybeEscapes' has '~Escapable' constraint preventing 'Escapable' conformance}} case just(T) case none } extension MaybeEscapes: Escapable where T: Escapable {} struct Escapes { // expected-note {{consider adding '~Escapable' to struct 'Escapes'}} let t: MaybeEscapes // expected-error {{stored property 't' of 'Escapable'-conforming struct 'Escapes' has non-Escapable type 'MaybeEscapes'}} } enum Boring { case thing(MaybeEscapes) } struct NonEscapingHasNoDeinit: ~Escapable { // expected-note {{consider adding '~Copyable' to struct 'NonEscapingHasNoDeinit'}} deinit {} // expected-error {{deinitializer cannot be declared in struct 'NonEscapingHasNoDeinit' that conforms to 'Copyable'}} } /// MARK: requirement conflict tests func conflict1(_ t: T) where T: NeedsCopyable, T: ~Copyable {} // expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}} func conflict2(_ t: AlwaysCopyable) {} // expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}} func conflict3a(_ t: T) {} // expected-error@-1 {{composition cannot contain '~Copyable' when another member requires 'Copyable'}} func conflict3b(_ t: T) where T: NeedsCopyable, T: ~Copyable {} // expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}} func conflict4a(_ t: some NeedsCopyable & ~Copyable) {} // expected-error@-1 {{composition cannot contain '~Copyable' when another member requires 'Copyable'}} protocol Conflict5: ~Copyable { borrowing func whatever() -> AlwaysCopyable // expected-error {{type 'Self' does not conform to protocol 'Copyable'}} } // expected-warning@+1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}} func conflict6(_ t: T, _ u: U) // expected-error {{'T' required to be 'Copyable' but is marked with '~Copyable'}} where U : NeedsCopyable, T == U {} protocol Conflict7 { associatedtype Element } func conflict7(_ t: T, _ u: U) where U: ~Copyable, // expected-error {{'U' required to be 'Copyable' but is marked with '~Copyable'}} T: Conflict7, U == T.Element {} protocol Conflict8: ~Copyable, NeedsCopyable {} // expected-error@-1 {{'Self' required to be 'Copyable' but is marked with '~Copyable'}} struct Conflict9 {} func conflict9(_ u: Conflict9) {} // expected-error@-1 {{'U' required to be 'Copyable' but is marked with '~Copyable'}} func conflict10(_ t: T, _ u: some ~Copyable & Copyable) // expected-error@-1 {{composition cannot contain '~Copyable' when another member requires 'Copyable'}} where T: Copyable, T: ~Copyable {} // expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}} protocol Conflict11: ~Copyable, Copyable {} // expected-error@-1 {{'Self' required to be 'Copyable' but is marked with '~Copyable'}} struct Conflict12: ~Copyable, Copyable {} // expected-error@-1 {{struct 'Conflict12' required to be 'Copyable' but is marked with '~Copyable'}} // FIXME: this is bogus (rdar://119346022) protocol Conflict13 { associatedtype A associatedtype B: ~Copyable } func conflict13(_ t: T) where T: Conflict13, T.A == T.B {} // expected-warning@+1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}} func conflict14(_ t: borrowing T, _ u: borrowing U) where T: ~Copyable, U: ~Escapable, T == U {} protocol Conflict15 { associatedtype HasE: ~Copyable associatedtype HasC: ~Escapable } func conflict15(_ t: T, _ c: C, _ e: borrowing E) where T: Conflict15, E: ~Copyable, // expected-error {{'E' required to be 'Copyable' but is marked with '~Copyable'}} E == T.HasC, C: ~Escapable, // expected-error {{'C' required to be 'Escapable' but is marked with '~Escapable'}} C == T.HasE {} // Class bounds and AnyObject class Soup {} func checkClassBound1(_ t: T) where T: ~Copyable, T: Soup {} // expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}} // expected-note@+2 3{{add}} // expected-error@+1 {{parameter of noncopyable type 'T' must specify ownership}} func checkClassBound2(_ t: T) where T: ~Escapable, T: AnyObject, T: ~Copyable {} // expected-error@-1 {{'T' required to be 'Escapable' but is marked with '~Escapable'}} // expected-error@-2 {{'T' required to be 'Copyable' but is marked with '~Copyable'}} func checkClassBound3(_ t: T) where T: Soup & ~Copyable & ~Escapable {} // expected-error@-1 {{composition involving class requirement 'Soup' cannot contain '~Copyable'}} func checkClassBound4(_ t: T) where T: Soup, T: ~Copyable & ~Escapable {} // expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}} // expected-error@-2 {{'T' required to be 'Escapable' but is marked with '~Escapable'}} public func checkAnyObjInv1(_ t: borrowing Result) where Result: ~Copyable {} // expected-error@-1 {{'Result' required to be 'Copyable' but is marked with '~Copyable'}} public func checkAnyObjInv2(_ t: borrowing Result) where Result: ~Escapable {} // expected-error@-1 {{'Result' required to be 'Escapable' but is marked with '~Escapable'}} public func checkAnyObject(_ t: Result) where Result: AnyObject { checkCopyable(t) } func checkExistentialAndClasses( _ a: any AnyObject & ~Copyable, // expected-error {{composition involving 'AnyObject' cannot contain '~Copyable'}} _ b: any Soup & Copyable & ~Escapable & ~Copyable, // expected-error@-1 {{composition involving class requirement 'Soup' cannot contain '~Copyable'}} _ c: some (~Escapable & Removed) & Soup // expected-error {{composition cannot contain '~Escapable' when another member requires 'Escapable'}} ) {} protocol HasNCBuddy: ~Copyable { associatedtype NCBuddy: HasNCBuddy, ~Copyable associatedtype Buddy: HasMember } protocol HasMember : HasNCBuddy { associatedtype Member: HasMember associatedtype NCMember: ~Copyable } func checkOwnership(_ t: T, _ l: T.NCBuddy.Buddy.Member.Buddy, _ m: T.Member.Member, _ n: T.Member.NCMember, // expected-error@-1 {{parameter of noncopyable type 'T.Member.NCMember' must specify ownership}} // expected-note@-1 3{{add}} _ o: T.Member.NCBuddy.NCBuddy // expected-error@-1 {{parameter of noncopyable type 'T.Member.NCBuddy.NCBuddy' must specify ownership}} // expected-note@-1 3{{add}} ) {} // Covers an issue when building Combine from its interface. public struct Record { public init(recording: Record) {} } protocol P {} extension Record : Decodable where Output : P {} struct Blahaj: ~Copyable { deinit {} // this is OK } extension Blahaj: Q where Value: Q {} // expected-error@-1 {{type 'Blahaj' does not conform to protocol 'Copyable'}} protocol Q: Copyable {} // expected-note@-1 {{type 'Blahaj' does not conform to inherited protocol 'Copyable'}} // expected-note@+2 3{{add}} // expected-error@+1 {{parameter of noncopyable type 'Blahaj' must specify ownership}} func testBlahaj(_ x: Blahaj, // expected-note@+2 3{{add}} // expected-error@+1 {{parameter of noncopyable type 'Blahaj' must specify ownership}} _ y: Blahaj) {} extension Int: NeedsCopyable {} func checkExistentials() { let _: any ~Escapable & (NeedsCopyable & ~Copyable) // expected-error {{composition cannot contain '~Copyable' when another member requires 'Copyable'}} let _: any NeedsCopyable & ~Copyable = 1 // expected-error {{composition cannot contain '~Copyable' when another member requires 'Copyable'}} let _: any NeedsCopyable & ~Escapable = 1 // expected-error {{composition cannot contain '~Escapable' when another member requires 'Escapable'}} let _: any Copyable & ~Copyable = 1 // expected-error {{composition cannot contain '~Copyable' when another member requires 'Copyable'}} let _: any Escapable & ~Escapable = 1 // expected-error {{composition cannot contain '~Escapable' when another member requires 'Escapable'}} } typealias NotCopyable = ~Copyable typealias EmptyComposition = ~Copyable & ~Escapable func test(_ t: borrowing NotCopyable) {} // expected-warning {{use of 'NotCopyable' (aka '~Copyable') as a type must be written 'any NotCopyable'}} func test(_ t: borrowing EmptyComposition) {} // expected-warning {{use of 'EmptyComposition' (aka '~Copyable & ~Escapable') as a type must be written 'any EmptyComposition' (aka 'any ~Copyable & ~Escapable')}} typealias Copy = Copyable func test(_ z1: Copy, _ z2: Copyable) {} // Conformances can be conditional on whether a generic parameter is Copyable protocol Arbitrary {} protocol AnotherOne {} struct UnethicalPointer {} extension UnethicalPointer: Arbitrary {} extension UnethicalPointer: AnotherOne where Pointee: Copyable {} struct AlsoLegal1 {} extension AlsoLegal1: Arbitrary {} extension AlsoLegal1: AnotherOne where Pointee: Escapable {} struct SillIllegal2 {} extension SillIllegal2: Arbitrary where Pointee: Sendable {} // expected-error@-1 {{conditional conformance to non-marker protocol 'Arbitrary' cannot depend on conformance of 'Pointee' to marker protocol 'Sendable'}} struct SSS: ~Copyable, PPP {} protocol PPP: ~Copyable {} let global__old__: any PPP = SSS() // expected-error {{value of type 'SSS' does not conform to specified type 'Copyable'}} let global__new__: any PPP & ~Copyable = SSS() struct Example {} struct TestResolution1 { // expected-note {{consider adding '~Copyable' to struct 'TestResolution1'}} var maybeNC: NC? = nil // expected-error {{stored property 'maybeNC' of 'Copyable'-conforming struct 'TestResolution1' has non-Copyable type 'NC?'}} } struct TestResolution2 { // expected-note {{consider adding '~Copyable' to struct 'TestResolution2'}} var maybeIOUNC: NC! = nil // expected-error {{stored property 'maybeIOUNC' of 'Copyable'-conforming struct 'TestResolution2' has non-Copyable type 'NC?'}} } struct TestResolution3 { var arrayNC: [NC] = [] // expected-error {{type 'NC' does not conform to protocol 'Copyable'}} var dictNC: [String: NC] = [:] // expected-error {{type 'NC' does not conform to protocol 'Copyable'}} var exampleNC: Example = Example() // expected-error {{type 'NC' does not conform to protocol 'Copyable'}} } public struct Box: ~Copyable {} // Box is never copyable, so we can't support this conditional conformance. public enum List: ~Copyable { case cons(Element, Box>) // expected-error {{associated value 'cons' of 'Copyable'-conforming generic enum 'List' has non-Copyable type '(Element, Box>)'}} case empty } extension List: Copyable where Element: Copyable {} struct Yapping {} extension Yapping { // expected-note {{'where T: Copyable' is implicit here}} func yap() {} } func testYap(_ y: Yapping) { y.yap() // expected-error {{referencing instance method 'yap()' on 'Yapping' requires that 'NC' conform to 'Copyable'}} } protocol Veggie: ~Copyable {} func generalized(_ x: Any.Type) {} func testMetatypes(_ t: (any Veggie & ~Copyable).Type) { generalized(t) // expected-error {{cannot convert value of type '(any Veggie & ~Copyable).Type' to expected argument type 'any Any.Type'}} }