forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsame_types.swift
155 lines (129 loc) · 3.72 KB
/
same_types.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// RUN: %target-parse-verify-swift
protocol Fooable {
typealias Foo
var foo: Foo { get }
}
protocol Barrable {
typealias Bar: Fooable
var bar: Bar { get }
}
struct X {}
struct Y: Fooable {
typealias Foo = X
var foo: X { return X() }
}
struct Z: Barrable {
typealias Bar = Y
var bar: Y { return Y() }
}
protocol TestSameTypeRequirement {
func foo<F1: Fooable where F1.Foo == X>(f: F1)
}
struct SatisfySameTypeRequirement : TestSameTypeRequirement {
func foo<F2: Fooable where F2.Foo == X>(f: F2) {}
}
func test1<T: Fooable where T.Foo == X>(fooable: T) -> X {
return fooable.foo
}
struct NestedConstraint<T> {
func tFoo<U: Fooable where U.Foo == T>(fooable: U) -> T {
return fooable.foo
}
}
func test2<
T: Fooable, U: Fooable
where
T.Foo == X, U.Foo == T.Foo
>(t: T, u: U) -> (X, X) {
return (t.foo, u.foo)
}
func test2a<
T: Fooable, U: Fooable
where
T.Foo == X, T.Foo == U.Foo
>(t: T, u: U) -> (X, X) {
return (t.foo, u.foo)
}
func test3<
T: Fooable, U: Fooable
where
T.Foo == X, U.Foo == X, T.Foo == U.Foo
>(t: T, u: U) -> (X, X) {
return (t.foo, u.foo)
}
func fail1<
T: Fooable, U: Fooable
where
T.Foo == X, U.Foo == Y, T.Foo == U.Foo // expected-error{{generic parameter 'Foo' cannot be equal to both 'X' and 'Y'}}
>(t: T, u: U) -> (X, Y) {
return (t.foo, u.foo)
}
func fail2<
T: Fooable, U: Fooable
where
T.Foo == U.Foo, T.Foo == X, U.Foo == Y // expected-error{{generic parameter 'Foo' cannot be equal to both 'X' and 'Y'}}
>(t: T, u: U) -> (X, Y) {
return (t.foo, u.foo) // expected-error{{cannot convert return expression of type 'X' to return type 'Y'}}
}
func test4<T: Barrable where T.Bar == Y>(t: T) -> Y {
return t.bar
}
func fail3<
T: Barrable
where
T.Bar == X // expected-error{{'X' does not conform to required protocol 'Fooable'}}
>(t: T) -> X {
return t.bar // expected-error{{cannot convert return expression of type 'T.Bar' to return type 'X'}}
}
func test5<T: Barrable where T.Bar.Foo == X>(t: T) -> X {
return t.bar.foo
}
func test6<T: Barrable where T.Bar == Y>(t: T) -> (Y, X) {
return (t.bar, t.bar.foo)
}
func test7<T: Barrable where T.Bar == Y, T.Bar.Foo == X>(t: T) -> (Y, X) {
return (t.bar, t.bar.foo)
}
func fail4<
T: Barrable
where
T.Bar == Y,
T.Bar.Foo == Z // expected-error{{generic parameter 'Foo' cannot be equal to both 'Foo' (aka 'X') and 'Z'}}
>(t: T) -> (Y, Z) {
return (t.bar, t.bar.foo) // expected-error{{cannot convert return expression of type 'X' to return type 'Z'}}
}
// TODO: repeat diagnostic
func fail5<
T: Barrable
where
T.Bar.Foo == Z,
T.Bar == Y // expected-error 2{{generic parameter 'Foo' cannot be equal to both 'Z' and 'Foo'}}
>(t: T) -> (Y, Z) {
return (t.bar, t.bar.foo) // expected-error{{cannot convert return expression of type 'X' to return type 'Z'}}
}
func test8<T: Fooable where T.Foo == X, T.Foo == Y>(t: T) {} // expected-error{{generic parameter 'Foo' cannot be equal to both 'X' and 'Y'}}
func testAssocTypeEquivalence<
T: Fooable where T.Foo == X
>(fooable: T) -> X.Type {
return T.Foo.self
}
func fail6<T where T == Int>(t: T) -> Int { // expected-error{{same-type requirement makes generic parameter 'T' non-generic}}
return t // expected-error{{cannot convert return expression of type 'T' to return type 'Int'}}
}
func test8<
T: Barrable, U: Barrable
where
T.Bar == Y, U.Bar.Foo == X, T.Bar == U.Bar
>(t: T, u: U) -> (Y, Y, X, X) {
return (t.bar, u.bar, t.bar.foo, u.bar.foo)
}
func test8a<
T: Barrable, U: Barrable
where
T.Bar == Y, U.Bar.Foo == X, U.Bar == T.Bar
>(t: T, u: U) -> (Y, Y, X, X) {
return (t.bar, u.bar, t.bar.foo, u.bar.foo)
}
// rdar://problem/19137463
func rdar19137463<T where T.a == T>(t: T) {} // expected-error{{'a' is not a member type of 'T'}}
rdar19137463(1)