Files
swift-mirror/test/Constraints/rdar39931339.swift
Slava Pestov 6d84c18ba4 Sema: Check 'where' clause requirements on type witnesses
In the included test case, conformance checking of Wrapper : B would
pick up typealias Foo as a witness for the associated type B.Foo.

However, this typealias Foo is defined in a constrained extension where
T : A, and the underlying type references the associated type A.Foo
on T.

The resulting substitution is invalid when the conformance Wrapper : B
is used in a context where T does not conform to A.

Instead, we should ignore this typealias entirely, since it appears
in an unusable constrained extension.

Fixes <rdar://problem/60219705>, <https://bugs.swift.org/browse/SR-12327>,
<https://bugs.swift.org/browse/SR-12663>.
2020-08-15 01:43:13 -04:00

49 lines
1.3 KiB
Swift

// RUN: %target-typecheck-verify-swift
protocol P {}
struct S<T> {}
class C : P {}
extension S where T : P { // expected-note {{where 'T' = 'T'}}
typealias A = Int
typealias B<U> = S<U>
}
extension S where T == Float { // expected-note {{requirement specified as 'T' == 'Float' [with T = Int]}}
typealias C = Int
}
class A<T, U> {}
extension A where T == [U], U: P {
typealias S1 = Int
}
extension A where T == [U], U == Int {
// expected-note@-1 {{requirement specified as 'T' == '[Int]' [with T = [String]]}}
typealias S2 = Int
}
class B<U> : A<[U], U> {}
_ = B<C>.S1() // Ok
_ = B<Int>.S2() // Ok
_ = B<Float>.S1() // expected-error {{type 'Float' does not conform to protocol 'P'}}
_ = B<String>.S2()
// expected-error@-1 {{'A<T, U>.S2' (aka 'Int') requires the types '[String]' and '[Int]' be equivalent}}
_ = S<C>.A() // Ok
_ = S<Int>.A() // expected-error {{type 'Int' does not conform to protocol 'P'}}
_ = S<String>.B<Int>() // expected-error {{type 'String' does not conform to protocol 'P'}}
_ = S<Int>.C() // expected-error {{'S<T>.C' (aka 'Int') requires the types 'Int' and 'Float' be equivalent}}
func foo<T>(_ s: S<T>.Type) {
_ = s.A() // expected-error {{referencing type alias 'A' on 'S' requires that 'T' conform to 'P'}}
}
func bar<T: P>(_ s: S<T>.Type) {
_ = s.A() // Ok
}