// RUN: %target-typecheck-verify-swift -target %target-swift-5.9-abi-triple class Class {} // A protocol member accessed with an existential value might have generic // constraints that require the ability to spell an opened archetype in order // to be satisfied. Such are // - superclass requirements, when the object is a non-'Self'-rooted type // parameter, and the subject is dependent on 'Self', e.g. U : G // - same-type requirements, when one side is dependent on 'Self', and the // other is a non-'Self'-rooted type parameter, e.g. U.Element == Self. // // Because opened archetypes are not part of the surface language, these // constraints render the member inaccessible. // // Note: 'Self'-rooted type parameters that are invalid in the context of the // existential base type are ignored -- the underlying requirement failure is // considered a more pressing issue. protocol UnfulfillableGenericRequirements { associatedtype A } extension UnfulfillableGenericRequirements { func method1() where A : Class {} func method2() where A: Sequence, A.Element == Self {} func method3(_: U) -> U {} func method4(_: U) where U : Class {} // expected-note@-1 3 {{where 'U' = 'Bool'}} func method5(_: U) where U: Sequence, Self == U.Element {} // expected-note@-1 {{where 'U' = 'Bool'}} // expected-note@+1 2 {{where 'U' = 'Bool'}} func method6(_: U) where U: UnfulfillableGenericRequirements, A: Sequence, A.Element: Sequence, U.A == A.Element.Element {} func method7(_: U) where U: UnfulfillableGenericRequirements & Class {} func method8(_: U) where U == Self.A {} } do { let exist: any UnfulfillableGenericRequirements exist.method1() // expected-error {{instance method 'method1()' requires that 'Self.A' inherit from 'Class'}} exist.method2() // expected-error@-1 {{instance method 'method2()' requires the types 'Self' and 'Self.A.Element' be equivalent}} // expected-error@-2 {{instance method 'method2()' requires that 'Self.A' conform to 'Sequence'}} _ = exist.method3(false) // ok exist.method4(false) // expected-error@-1 {{instance method 'method4' requires that 'Bool' inherit from 'Class'}} // expected-error@-2 {{member 'method4' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} exist.method5(false) // expected-error@-1 {{instance method 'method5' requires that 'Bool' conform to 'Sequence'}} // expected-error@-2 {{member 'method5' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} exist.method7(false) // expected-error@-1 {{instance method 'method7' requires that 'U' conform to 'UnfulfillableGenericRequirements'}} // expected-error@-2 {{member 'method7' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} exist.method8(false) // expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} } // Make sure this also works in a generic context! struct G { func doIt() { let exist: any UnfulfillableGenericRequirements exist.method8(false) // expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}} } } protocol UnfulfillableGenericRequirementsDerived1: UnfulfillableGenericRequirements where A == Bool {} protocol UnfulfillableGenericRequirementsDerived2: UnfulfillableGenericRequirements where A == Class {} do { // Test that 'Self' dependencies are computed relative to the base type. let exist1: any UnfulfillableGenericRequirementsDerived1 let exist2: any UnfulfillableGenericRequirementsDerived2 exist1.method4(false) // expected-error@-1 {{instance method 'method4' requires that 'Bool' inherit from 'Class}} exist2.method4(false) // expected-error@-1 {{member 'method4' cannot be used on value of type 'any UnfulfillableGenericRequirementsDerived2'; consider using a generic constraint instead}} // expected-error@-2 {{instance method 'method4' requires that 'Bool' inherit from 'Class'}} } protocol UnfulfillableGenericRequirementsDerived3: UnfulfillableGenericRequirements where A: Sequence, A.Element: Sequence {} do { // Test that 'Self'-rooted type parameters that are invalid in the context of // the existential base type are ignored. let exist1: any UnfulfillableGenericRequirements let exist2: any UnfulfillableGenericRequirementsDerived3 exist1.method6(false) // expected-error@-1 {{instance method 'method6' requires that 'Self.A.Element' conform to 'Sequence'}} // expected-error@-2 {{instance method 'method6' requires that 'Self.A' conform to 'Sequence'}} // expected-error@-3 {{instance method 'method6' requires that 'Bool' conform to 'UnfulfillableGenericRequirements'}} exist2.method6(false) // expected-error@-1 {{member 'method6' cannot be used on value of type 'any UnfulfillableGenericRequirementsDerived3'; consider using a generic constraint instead}} // expected-error@-2 {{instance method 'method6' requires that 'Bool' conform to 'UnfulfillableGenericRequirements'}} } // Test that we don't determine existential availability based on type // parameters that are invalid in the context of the existential base type -- // the requirement failure is a more pressing issue. protocol InvalidTypeParameters { associatedtype A } extension InvalidTypeParameters { func method1() -> A.A where A: InvalidTypeParameters {} func method2(_: A.A) where A: InvalidTypeParameters {} func method3(_: A.A, _: A) where A: InvalidTypeParameters {} } do { let exist: any InvalidTypeParameters exist.method1() // expected-error {{instance method 'method1()' requires that 'Self.A' conform to 'InvalidTypeParameters'}} exist.method2(false) // expected-error {{instance method 'method2' requires that 'Self.A' conform to 'InvalidTypeParameters'}} exist.method3(false, false) // expected-error {{instance method 'method3' requires that 'Self.A' conform to 'InvalidTypeParameters'}} // expected-error@-1 {{member 'method3' cannot be used on value of type 'any InvalidTypeParameters'; consider using a generic constraint instead}} } protocol GenericRequirementFailures { associatedtype A } extension GenericRequirementFailures where A == Never { func method1() {} func method2() -> Self {} func method3(_: A) {} } extension GenericRequirementFailures where A: GenericRequirementFailures { func method4() {} } do { let exist: any GenericRequirementFailures exist.method1() // expected-error {{referencing instance method 'method1()' on 'GenericRequirementFailures' requires the types 'Self.A' and 'Never' be equivalent}} exist.method2() // expected-error {{referencing instance method 'method2()' on 'GenericRequirementFailures' requires the types 'Self.A' and 'Never' be equivalent}} exist.method3(false) // expected-error {{referencing instance method 'method3' on 'GenericRequirementFailures' requires the types 'Self.A' and 'Never' be equivalent}} // expected-error@-1 {{member 'method3' cannot be used on value of type 'any GenericRequirementFailures'; consider using a generic constraint instead}} exist.method4() // expected-error {{referencing instance method 'method4()' on 'GenericRequirementFailures' requires that 'Self.A' conform to 'GenericRequirementFailures'}} } protocol GenericRequirementFailuresDerived: GenericRequirementFailures where A: GenericRequirementFailures {} do { let exist: any GenericRequirementFailuresDerived exist.method4() // ok }