@@ -72,20 +72,49 @@ fn ref_lifetime_variance() {
7272}
7373
7474#[ test]
75- fn fn_lifetime_variance ( ) {
75+ fn fn_lifetime_variance_args ( ) {
7676 test ! {
7777 program {
7878 }
7979
8080 goal {
81- Subtype ( for <' a, ' b> fn ( & ' a u32 , & ' b u32 ) , for <' a> fn ( & ' a u32 , & ' a u32 ) )
81+ for <' a, ' b> fn ( & ' a u32 , & ' b u32 ) = for <' a> fn ( & ' a u32 , & ' a u32 )
8282 } yields {
83+ "Unique;substitution [], lifetime constraints [\
84+ InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \
85+ InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"
86+ }
87+ }
88+ }
89+
90+ #[ test]
91+ fn fn_lifetime_variance_with_return_type ( ) {
92+ test ! {
93+ program {
94+ }
95+
96+ goal {
97+ Subtype ( for <' a, ' b> fn ( & ' a u32 , & ' b u32 ) -> & ' a u32 , for <' a> fn ( & ' a u32 , & ' a u32 ) -> & ' a u32 )
98+ } yields {
99+ // TODO: are these results actually correct?
83100 "Unique; for<?U1,?U1> { substitution [], lifetime constraints [\
84- InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
85- InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }] }"
101+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
102+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, \
103+ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 } \
104+ ]}"
105+ }
106+ goal {
107+ Subtype ( for <' a> fn ( & ' a u32 , & ' a u32 ) -> & ' a u32 , for <' a, ' b> fn ( & ' a u32 , & ' b u32 ) -> & ' a u32 )
108+ } yields {
109+ "Unique; for<?U1> { substitution [], lifetime constraints [\
110+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
111+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, \
112+ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 } \
113+ ] }"
86114 }
87115 }
88116}
117+
89118#[ test]
90119fn generalize ( ) {
91120 test ! {
@@ -108,6 +137,8 @@ fn generalize() {
108137 }
109138}
110139
140+ /// Tests that the generalizer correctly generalizes lifetimes (as opposed to
141+ /// just that variance in general works).
111142#[ test]
112143fn multi_lifetime ( ) {
113144 test ! {
@@ -121,6 +152,160 @@ fn multi_lifetime() {
121152 }
122153 }
123154 } yields {
155+ // Without the generalizer, we would yield a result like this:
156+ //
157+ // "Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime
158+ // constraints [InEnvironment { environment: Env([]), goal: '!1_1: '!1_0
159+ // }]"
160+ //
161+ // This is incorrect, as we shouldn't be requiring 'a and 'b to be
162+ // related to eachother. Instead, U should be &'?1 u32, with constraints
163+ // ?1 : 'a, ?1: 'b.
164+ "Unique; for<?U1> { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\
165+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
166+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"
167+ }
168+ }
169+ }
170+
171+ /// Tests that the generalizer generalizes lifetimes within a covariant struct.
172+ #[ test]
173+ fn multi_lifetime_covariant_struct ( ) {
174+ test ! {
175+ program {
176+ #[ variance( Covariant ) ]
177+ struct Foo <A > { }
178+ }
179+
180+ goal {
181+ forall<' a, ' b> {
182+ exists<U > {
183+ Subtype ( Foo <& ' a u32 >, Foo <U >) ,
184+ Subtype ( Foo <& ' b u32 >, Foo <U >)
185+ }
186+ }
187+ } yields {
188+ // Result should be identical to multi_lifetime result.
189+ "Unique; for<?U1> { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\
190+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
191+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"
192+ }
193+ }
194+ }
195+
196+ /// Tests that the generalizer generalizes lifetimes within a contravariant
197+ /// struct, and that that variance contravariance is recognized.
198+ #[ test]
199+ fn multi_lifetime_contravariant_struct ( ) {
200+ test ! {
201+ program {
202+ #[ variance( Contravariant ) ]
203+ struct Foo <A > { }
204+ }
205+
206+ goal {
207+ forall<' a, ' b> {
208+ exists<U > {
209+ Subtype ( Foo <& ' a u32 >, Foo <U >) ,
210+ Subtype ( Foo <& ' b u32 >, Foo <U >)
211+ }
212+ }
213+ } yields {
214+ // Result should be opposite multi_lifetime result.
215+ "Unique; for<?U1> { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\
216+ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \
217+ InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"
218+ }
219+ }
220+ }
221+
222+ /// Tests that the generalizer generalizes lifetimes within a invariant struct.
223+ #[ test]
224+ fn multi_lifetime_invariant_struct ( ) {
225+ test ! {
226+ program {
227+ #[ variance( Invariant ) ]
228+ struct Foo <A > { }
229+ }
230+
231+ goal {
232+ forall<' a, ' b> {
233+ exists<U > {
234+ Subtype ( Foo <& ' a u32 >, Foo <U >) ,
235+ Subtype ( Foo <& ' b u32 >, Foo <U >)
236+ }
237+ }
238+ } yields {
239+ // Because A is invariant, we require the lifetimes to be equal
240+ "Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime
241+ constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \
242+ InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"
243+ }
244+ }
245+ }
246+
247+ /// Tests that the generalizer generalizes lifetimes within slices correctly.
248+ #[ test]
249+ fn multi_lifetime_slice ( ) {
250+ test ! {
251+ program {
252+ }
253+
254+ goal {
255+ forall<' a, ' b> {
256+ exists<U > {
257+ Subtype ( [ & ' a u32 ] , [ U ] ) ,
258+ Subtype ( [ & ' b u32 ] , [ U ] )
259+ }
260+ }
261+ } yields {
262+ // Result should be identical to multi_lifetime result.
263+ "Unique; for<?U1> { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\
264+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
265+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"
266+ }
267+ }
268+ }
269+
270+ /// Tests that the generalizer generalizes lifetimes within tuples correctly.
271+ #[ test]
272+ fn multi_lifetime_tuple ( ) {
273+ test ! {
274+ program {
275+ }
276+
277+ goal {
278+ forall<' a, ' b> {
279+ exists<U > {
280+ Subtype ( ( & ' a u32 , & ' a u32 ) , [ U ] ) ,
281+ Subtype ( ( & ' b u32 , & ' b u32 ) , [ U ] )
282+ }
283+ }
284+ } yields {
285+ // Result should be identical to multi_lifetime result.
286+ "Unique; for<?U1> { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\
287+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
288+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"
289+ }
290+ }
291+ }
292+
293+ /// Tests that the generalizer generalizes lifetimes within tuples correctly.
294+ #[ test]
295+ fn multi_lifetime_array ( ) {
296+ test ! {
297+ program {
298+ }
299+
300+ goal {
301+ forall<' a, ' b> {
302+ exists<U > {
303+ Subtype ( [ & ' a u32 ; 16 ] , [ U ] ) ,
304+ Subtype ( [ & ' b u32 ; 16 ] , [ U ] )
305+ }
306+ }
307+ } yields {
308+ // Result should be identical to multi_lifetime result.
124309 "Unique; for<?U1> { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\
125310 InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
126311 InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"
0 commit comments