Skip to content

Commit 22a21fa

Browse files
committed
test: Split up existential_member_accesses_self_assoctype.swift
1 parent 73cabe3 commit 22a21fa

File tree

10 files changed

+1093
-1058
lines changed

10 files changed

+1093
-1058
lines changed

test/decl/protocol/existential_member_access/basic.swift

Lines changed: 555 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-swift-5.9-abi-triple
2+
3+
struct Struct<T> {
4+
class Nested {}
5+
struct NestedGeneric<U> {}
6+
}
7+
class Class<T> {}
8+
9+
// Test that a reference to a 'Self'-rooted dependent member type does not
10+
// affect the ability to reference a protocol member on an existential when
11+
// it is *fully* concrete.
12+
protocol ConcreteAssocTypes {
13+
associatedtype A1 where A1 == Struct<Self>
14+
associatedtype A2 where A2 == (Bool, Self)
15+
associatedtype A3 where A3 == any Class<A4> & ConcreteAssocTypes
16+
associatedtype A4
17+
18+
func method1(_: A1)
19+
func method2() -> Struct<A2>
20+
func method3(_: A3)
21+
22+
var property1: A1 { get }
23+
var property2: A2 { get }
24+
var property3: A3 { get }
25+
26+
subscript(subscript1 _: A3) -> Bool { get }
27+
subscript(subscript2 _: Bool) -> A1 { get }
28+
subscript(subscript3 _: A2) -> Bool { get }
29+
30+
associatedtype A5 where A5 == Bool
31+
associatedtype A6 where A6 == any ConcreteAssocTypes
32+
associatedtype A7 where A7 == A8.A5
33+
associatedtype A8: ConcreteAssocTypes
34+
35+
func method4(_: Struct<A5>, _: A6.Type, _: () -> A5) -> any Class<Struct<A7>.Nested> & ConcreteAssocTypes
36+
37+
var property4: (Struct<A5>, A6.Type, () -> A5) -> any Class<Struct<A7>.Nested> & ConcreteAssocTypes { get }
38+
39+
subscript(subscript4 _: Struct<A5>, _: A6.Type, _: () -> A5) -> any Class<Struct<A7>.Nested> & ConcreteAssocTypes { get }
40+
}
41+
do {
42+
let exist: any ConcreteAssocTypes
43+
44+
let _ = exist.method1 // expected-error {{member 'method1' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
45+
let _ = exist.method2 // expected-error {{member 'method2' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
46+
let _ = exist.method3 // expected-error {{member 'method3' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
47+
let _ = exist.property1 // expected-error {{member 'property1' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
48+
// Covariant 'Self' erasure works in conjunction with concrete associated types.
49+
let _: (Bool, any ConcreteAssocTypes) = exist.property2 // ok
50+
let _ = exist.property3 // expected-error {{member 'property3' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
51+
let _ = exist[subscript1: false] // expected-error {{member 'subscript' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
52+
let _ = exist[subscript2: false] // expected-error {{member 'subscript' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
53+
let _ = exist[subscript3: false] // expected-error {{member 'subscript' cannot be used on value of type 'any ConcreteAssocTypes'; consider using a generic constraint instead}}
54+
55+
let _: (
56+
Struct<Bool>, (any ConcreteAssocTypes).Type, () -> Bool
57+
) -> any Class<Struct<Bool>.Nested> & ConcreteAssocTypes = exist.method4
58+
59+
let _: (
60+
Struct<Bool>, (any ConcreteAssocTypes).Type, () -> Bool
61+
) -> any Class<Struct<Bool>.Nested> & ConcreteAssocTypes = exist.property4
62+
63+
let _: any Class<Struct<Bool>.Nested> & ConcreteAssocTypes =
64+
exist[
65+
subscript4: Struct<Bool>(), (any ConcreteAssocTypes).self, { true }
66+
]
67+
}
68+
69+
protocol ConcreteAssocTypeComposition1 {
70+
associatedtype A
71+
func method(_: A)
72+
}
73+
protocol ConcreteAssocTypeComposition2 where A == Bool {
74+
associatedtype A
75+
}
76+
do {
77+
let exist: any ConcreteAssocTypeComposition1 & ConcreteAssocTypeComposition2
78+
exist.method(true) // ok
79+
}
80+
81+
// Edge case: an associated type can be resolved through a class conformance.
82+
class Class1Simple: ConcreteAssocTypeThroughClass {
83+
typealias A = Bool
84+
}
85+
class Class1Generic<A>: ConcreteAssocTypeThroughClass {
86+
}
87+
protocol ConcreteAssocTypeThroughClass {
88+
associatedtype A
89+
}
90+
protocol ConcreteAssocTypeThroughClassRefined: ConcreteAssocTypeThroughClass {
91+
func method(_: A)
92+
}
93+
extension ConcreteAssocTypeThroughClassRefined {
94+
func test(arg1: any ConcreteAssocTypeThroughClassRefined & Class1Generic<Self>,
95+
arg2: any ConcreteAssocTypeThroughClassRefined & Class1Simple) {
96+
arg1.method(self) // ok
97+
arg2.method(true) // ok
98+
}
99+
}
100+
101+
protocol ConcreteAssocTypeCollision1 where A == Bool {
102+
associatedtype A
103+
func method(_: A)
104+
}
105+
protocol ConcreteAssocTypeCollision2 where A == Never {
106+
associatedtype A
107+
}
108+
do {
109+
let exist: any ConcreteAssocTypeCollision1 & ConcreteAssocTypeCollision2
110+
// FIXME: Should 'A' be ambiguous here?
111+
exist.method(true)
112+
}
113+
114+
class BadConformanceClass: CompositionBrokenClassConformance_a {}
115+
// expected-error@-1 {{type 'BadConformanceClass' does not conform to protocol 'CompositionBrokenClassConformance_a'}}
116+
// expected-note@-2 {{add stubs for conformance}}
117+
protocol CompositionBrokenClassConformance_a {
118+
associatedtype A // expected-note {{protocol requires nested type 'A'}}
119+
}
120+
protocol CompositionBrokenClassConformance_b: CompositionBrokenClassConformance_a {
121+
func method(_: A)
122+
}
123+
do {
124+
// FIXME: Should GenericSignature::getConcreteType return the null type instead
125+
// of the error type here for Self.A, despite the broken conformance?
126+
let exist: any CompositionBrokenClassConformance_b & BadConformanceClass
127+
exist.method(false) // expected-error {{type of expression is ambiguous without a type annotation}}
128+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-swift-5.9-abi-triple
2+
3+
class Class<T> {}
4+
5+
// A protocol member accessed with an existential value might have generic
6+
// constraints that require the ability to spell an opened archetype in order
7+
// to be satisfied. Such are
8+
// - superclass requirements, when the object is a non-'Self'-rooted type
9+
// parameter, and the subject is dependent on 'Self', e.g. U : G<Self.A>
10+
// - same-type requirements, when one side is dependent on 'Self', and the
11+
// other is a non-'Self'-rooted type parameter, e.g. U.Element == Self.
12+
//
13+
// Because opened archetypes are not part of the surface language, these
14+
// constraints render the member inaccessible.
15+
//
16+
// Note: 'Self'-rooted type parameters that are invalid in the context of the
17+
// existential base type are ignored -- the underlying requirement failure is
18+
// considered a more pressing issue.
19+
protocol UnfulfillableGenericRequirements {
20+
associatedtype A
21+
}
22+
extension UnfulfillableGenericRequirements {
23+
func method1() where A : Class<Self> {}
24+
func method2() where A: Sequence, A.Element == Self {}
25+
func method3<U>(_: U) -> U {}
26+
func method4<U>(_: U) where U : Class<Self.A> {}
27+
// expected-note@-1 3 {{where 'U' = 'Bool'}}
28+
func method5<U>(_: U) where U: Sequence, Self == U.Element {}
29+
// expected-note@-1 {{where 'U' = 'Bool'}}
30+
31+
// expected-note@+1 2 {{where 'U' = 'Bool'}}
32+
func method6<U>(_: U) where U: UnfulfillableGenericRequirements,
33+
A: Sequence, A.Element: Sequence,
34+
U.A == A.Element.Element {}
35+
func method7<U>(_: U) where U: UnfulfillableGenericRequirements & Class<Self> {}
36+
37+
func method8<U>(_: U) where U == Self.A {}
38+
}
39+
do {
40+
let exist: any UnfulfillableGenericRequirements
41+
42+
exist.method1() // expected-error {{instance method 'method1()' requires that 'Self.A' inherit from 'Class<Self>'}}
43+
exist.method2()
44+
// expected-error@-1 {{instance method 'method2()' requires the types 'Self' and 'Self.A.Element' be equivalent}}
45+
// expected-error@-2 {{instance method 'method2()' requires that 'Self.A' conform to 'Sequence'}}
46+
_ = exist.method3(false) // ok
47+
exist.method4(false)
48+
// expected-error@-1 {{instance method 'method4' requires that 'Bool' inherit from 'Class<Self.A>'}}
49+
// expected-error@-2 {{member 'method4' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
50+
exist.method5(false)
51+
// expected-error@-1 {{instance method 'method5' requires that 'Bool' conform to 'Sequence'}}
52+
// expected-error@-2 {{member 'method5' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
53+
54+
exist.method7(false)
55+
// expected-error@-1 {{instance method 'method7' requires that 'U' conform to 'UnfulfillableGenericRequirements'}}
56+
// expected-error@-2 {{member 'method7' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
57+
58+
exist.method8(false)
59+
// expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
60+
}
61+
62+
// Make sure this also works in a generic context!
63+
struct G<X, Y, Z> {
64+
func doIt() {
65+
let exist: any UnfulfillableGenericRequirements
66+
67+
exist.method8(false)
68+
// expected-error@-1 {{member 'method8' cannot be used on value of type 'any UnfulfillableGenericRequirements'; consider using a generic constraint instead}}
69+
}
70+
}
71+
protocol UnfulfillableGenericRequirementsDerived1: UnfulfillableGenericRequirements where A == Bool {}
72+
protocol UnfulfillableGenericRequirementsDerived2: UnfulfillableGenericRequirements where A == Class<Self> {}
73+
do {
74+
// Test that 'Self' dependencies are computed relative to the base type.
75+
let exist1: any UnfulfillableGenericRequirementsDerived1
76+
let exist2: any UnfulfillableGenericRequirementsDerived2
77+
78+
exist1.method4(false)
79+
// expected-error@-1 {{instance method 'method4' requires that 'Bool' inherit from 'Class<Self.A>}}
80+
exist2.method4(false)
81+
// expected-error@-1 {{member 'method4' cannot be used on value of type 'any UnfulfillableGenericRequirementsDerived2'; consider using a generic constraint instead}}
82+
// expected-error@-2 {{instance method 'method4' requires that 'Bool' inherit from 'Class<Self.A>'}}
83+
}
84+
protocol UnfulfillableGenericRequirementsDerived3: UnfulfillableGenericRequirements where A: Sequence, A.Element: Sequence {}
85+
do {
86+
// Test that 'Self'-rooted type parameters that are invalid in the context of
87+
// the existential base type are ignored.
88+
let exist1: any UnfulfillableGenericRequirements
89+
let exist2: any UnfulfillableGenericRequirementsDerived3
90+
91+
exist1.method6(false)
92+
// expected-error@-1 {{instance method 'method6' requires that 'Self.A.Element' conform to 'Sequence'}}
93+
// expected-error@-2 {{instance method 'method6' requires that 'Self.A' conform to 'Sequence'}}
94+
// expected-error@-3 {{instance method 'method6' requires that 'Bool' conform to 'UnfulfillableGenericRequirements'}}
95+
exist2.method6(false)
96+
// expected-error@-1 {{member 'method6' cannot be used on value of type 'any UnfulfillableGenericRequirementsDerived3'; consider using a generic constraint instead}}
97+
// expected-error@-2 {{instance method 'method6' requires that 'Bool' conform to 'UnfulfillableGenericRequirements'}}
98+
}
99+
100+
// Test that we don't determine existential availability based on type
101+
// parameters that are invalid in the context of the existential base type --
102+
// the requirement failure is a more pressing issue.
103+
protocol InvalidTypeParameters {
104+
associatedtype A
105+
}
106+
extension InvalidTypeParameters {
107+
func method1() -> A.A where A: InvalidTypeParameters {}
108+
func method2(_: A.A) where A: InvalidTypeParameters {}
109+
func method3(_: A.A, _: A) where A: InvalidTypeParameters {}
110+
}
111+
do {
112+
let exist: any InvalidTypeParameters
113+
114+
exist.method1() // expected-error {{instance method 'method1()' requires that 'Self.A' conform to 'InvalidTypeParameters'}}
115+
exist.method2(false) // expected-error {{instance method 'method2' requires that 'Self.A' conform to 'InvalidTypeParameters'}}
116+
exist.method3(false, false) // expected-error {{instance method 'method3' requires that 'Self.A' conform to 'InvalidTypeParameters'}}
117+
// expected-error@-1 {{member 'method3' cannot be used on value of type 'any InvalidTypeParameters'; consider using a generic constraint instead}}
118+
}
119+
120+
protocol GenericRequirementFailures {
121+
associatedtype A
122+
}
123+
extension GenericRequirementFailures where A == Never {
124+
func method1() {}
125+
func method2() -> Self {}
126+
func method3(_: A) {}
127+
}
128+
extension GenericRequirementFailures where A: GenericRequirementFailures {
129+
func method4() {}
130+
}
131+
do {
132+
let exist: any GenericRequirementFailures
133+
134+
exist.method1() // expected-error {{referencing instance method 'method1()' on 'GenericRequirementFailures' requires the types 'Self.A' and 'Never' be equivalent}}
135+
exist.method2() // expected-error {{referencing instance method 'method2()' on 'GenericRequirementFailures' requires the types 'Self.A' and 'Never' be equivalent}}
136+
exist.method3(false) // expected-error {{referencing instance method 'method3' on 'GenericRequirementFailures' requires the types 'Self.A' and 'Never' be equivalent}}
137+
// expected-error@-1 {{member 'method3' cannot be used on value of type 'any GenericRequirementFailures'; consider using a generic constraint instead}}
138+
exist.method4() // expected-error {{referencing instance method 'method4()' on 'GenericRequirementFailures' requires that 'Self.A' conform to 'GenericRequirementFailures'}}
139+
}
140+
protocol GenericRequirementFailuresDerived: GenericRequirementFailures where A: GenericRequirementFailures {}
141+
do {
142+
let exist: any GenericRequirementFailuresDerived
143+
exist.method4() // ok
144+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-swift-5.9-abi-triple
2+
3+
class ClassBase {}
4+
class ClassDerived<T>: ClassBase {}
5+
6+
protocol CovariantAssocTypeErasure {
7+
associatedtype A1
8+
associatedtype A2: AnyObject
9+
associatedtype A3: CovariantAssocTypeErasure
10+
associatedtype A4: ClassBase
11+
associatedtype A5: ClassDerived<Self>
12+
associatedtype A6: CovariantAssocTypeErasure & ClassBase
13+
associatedtype A7: ClassDerived<Self> & CovariantAssocTypeErasure
14+
15+
associatedtype B1 where B1 == Optional<A1>
16+
associatedtype B2 where B2 == (A2, Bool)
17+
associatedtype B3 where B3 == A3.Type
18+
associatedtype B4 where B4 == Array<A4>
19+
associatedtype B5 where B5 == Dictionary<String, A5>
20+
21+
func method1() -> A1
22+
func method2() -> A2
23+
func method3() -> A3
24+
func method4() -> A4
25+
func method5() -> A5
26+
func method6() -> A6
27+
func method7() -> A7
28+
29+
func method8() -> B1
30+
func method9() -> B2
31+
func method10() -> B3
32+
func method11() -> B4
33+
func method12() -> B5
34+
}
35+
protocol CovariantAssocTypeErasureDerived: CovariantAssocTypeErasure
36+
where A1: CovariantAssocTypeErasureDerived,
37+
A2: ClassBase,
38+
A3: CovariantAssocTypeErasureDerived,
39+
A4: CovariantAssocTypeErasureDerived,
40+
A5: CovariantAssocTypeErasureDerived,
41+
A6: CovariantAssocTypeErasureDerived,
42+
A7: Sequence {}
43+
do {
44+
let exist: any CovariantAssocTypeErasure
45+
46+
let _: Any = exist.method1()
47+
let _: AnyObject = exist.method2()
48+
let _: any CovariantAssocTypeErasure = exist.method3()
49+
let _: ClassBase = exist.method4()
50+
let _: ClassBase = exist.method5()
51+
let _: any ClassBase & CovariantAssocTypeErasure = exist.method6()
52+
let _: any ClassBase & CovariantAssocTypeErasure = exist.method7()
53+
let _: Any? = exist.method8()
54+
let _: (AnyObject, Bool) = exist.method9()
55+
let _: any CovariantAssocTypeErasure.Type = exist.method10()
56+
let _: Array<ClassBase> = exist.method11()
57+
let _: Dictionary<String, ClassBase> = exist.method12()
58+
59+
let _ = exist.method1()
60+
let _ = exist.method2()
61+
let _ = exist.method3()
62+
let _ = exist.method4()
63+
let _ = exist.method5()
64+
let _ = exist.method6()
65+
let _ = exist.method7()
66+
let _ = exist.method8()
67+
let _ = exist.method9()
68+
let _ = exist.method10()
69+
let _ = exist.method11()
70+
let _ = exist.method12()
71+
}
72+
do {
73+
let exist: any CovariantAssocTypeErasureDerived
74+
75+
let _: any CovariantAssocTypeErasureDerived = exist.method1()
76+
let _: ClassBase = exist.method2()
77+
let _: any CovariantAssocTypeErasureDerived = exist.method3()
78+
let _: any ClassBase & CovariantAssocTypeErasureDerived = exist.method4()
79+
let _: any ClassBase & CovariantAssocTypeErasureDerived = exist.method5()
80+
let _: any ClassBase & CovariantAssocTypeErasureDerived = exist.method6()
81+
let _: any ClassBase & CovariantAssocTypeErasure & Sequence = exist.method7()
82+
83+
let _: (any CovariantAssocTypeErasureDerived)? = exist.method8()
84+
let _: (ClassBase, Bool) = exist.method9()
85+
let _: any CovariantAssocTypeErasureDerived.Type = exist.method10()
86+
let _: Array<any ClassBase & CovariantAssocTypeErasureDerived> = exist.method11()
87+
let _: Dictionary<String, any ClassBase & CovariantAssocTypeErasureDerived> = exist.method12()
88+
}

0 commit comments

Comments
 (0)