mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
145 lines
7.6 KiB
Swift
145 lines
7.6 KiB
Swift
// RUN: %target-typecheck-verify-swift -target %target-swift-5.9-abi-triple
|
|
|
|
class Class<T> {}
|
|
|
|
// 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<Self.A>
|
|
// - 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<Self> {}
|
|
func method2() where A: Sequence, A.Element == Self {}
|
|
func method3<U>(_: U) -> U {}
|
|
func method4<U>(_: U) where U : Class<Self.A> {}
|
|
// expected-note@-1 3 {{where 'U' = 'Bool'}}
|
|
func method5<U>(_: U) where U: Sequence, Self == U.Element {}
|
|
// expected-note@-1 {{where 'U' = 'Bool'}}
|
|
|
|
// expected-note@+1 2 {{where 'U' = 'Bool'}}
|
|
func method6<U>(_: U) where U: UnfulfillableGenericRequirements,
|
|
A: Sequence, A.Element: Sequence,
|
|
U.A == A.Element.Element {}
|
|
func method7<U>(_: U) where U: UnfulfillableGenericRequirements & Class<Self> {}
|
|
|
|
func method8<U>(_: U) where U == Self.A {}
|
|
}
|
|
do {
|
|
let exist: any UnfulfillableGenericRequirements
|
|
|
|
exist.method1() // expected-error {{instance method 'method1()' requires that 'Self.A' inherit from 'Class<Self>'}}
|
|
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<Self.A>'}}
|
|
// 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<X, Y, Z> {
|
|
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<Self> {}
|
|
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<Self.A>}}
|
|
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<Self.A>'}}
|
|
}
|
|
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
|
|
}
|