@@ -137,8 +137,7 @@ fn generalize() {
137137 }
138138}
139139
140- /// Tests that the generalizer correctly generalizes lifetimes (as opposed to
141- /// just that variance in general works).
140+ /// Tests that the generalizer correctly generalizes lifetimes.
142141#[ test]
143142fn multi_lifetime ( ) {
144143 test ! {
@@ -168,7 +167,7 @@ fn multi_lifetime() {
168167 }
169168}
170169
171- /// Tests that the generalizer generalizes lifetimes within a covariant struct .
170+ /// Tests that we handle variance for covariant structs correctly .
172171#[ test]
173172fn multi_lifetime_covariant_struct ( ) {
174173 test ! {
@@ -193,8 +192,7 @@ fn multi_lifetime_covariant_struct() {
193192 }
194193}
195194
196- /// Tests that the generalizer generalizes lifetimes within a contravariant
197- /// struct, and that that variance contravariance is recognized.
195+ /// Tests that we handle variance for contravariant structs correctly.
198196#[ test]
199197fn multi_lifetime_contravariant_struct ( ) {
200198 test ! {
@@ -219,7 +217,7 @@ fn multi_lifetime_contravariant_struct() {
219217 }
220218}
221219
222- /// Tests that the generalizer generalizes lifetimes within a invariant struct .
220+ /// Tests that we handle variance for invariant structs correctly .
223221#[ test]
224222fn multi_lifetime_invariant_struct ( ) {
225223 test ! {
@@ -251,7 +249,7 @@ fn multi_lifetime_invariant_struct() {
251249 }
252250}
253251
254- /// Tests that the generalizer generalizes lifetimes within slices correctly.
252+ /// Tests that we handle variance for slices correctly.
255253#[ test]
256254fn multi_lifetime_slice ( ) {
257255 test ! {
@@ -274,7 +272,7 @@ fn multi_lifetime_slice() {
274272 }
275273}
276274
277- /// Tests that the generalizer generalizes lifetimes within tuples correctly.
275+ /// Tests that we handle variance for tuples correctly.
278276#[ test]
279277fn multi_lifetime_tuple ( ) {
280278 test ! {
@@ -297,7 +295,7 @@ fn multi_lifetime_tuple() {
297295 }
298296}
299297
300- /// Tests that the generalizer generalizes lifetimes within tuples correctly.
298+ /// Tests that we handle variance for arrays correctly.
301299#[ test]
302300fn multi_lifetime_array ( ) {
303301 test ! {
@@ -314,8 +312,188 @@ fn multi_lifetime_array() {
314312 } yields {
315313 // Result should be identical to multi_lifetime result.
316314 "Unique; for<?U1> { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\
317- InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
318- InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"
315+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
316+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \
317+ ]}"
318+ }
319+ }
320+ }
321+
322+ /// Tests that the generalizer recurses into covariant structs correctly.
323+ #[ test]
324+ fn generalize_covariant_struct ( ) {
325+ test ! {
326+ program {
327+ #[ variance( Covariant ) ]
328+ struct Foo <A > { }
329+ }
330+
331+ goal {
332+ forall<' a, ' b> {
333+ exists<U > {
334+ Subtype ( Foo <& ' a u32 >, U ) ,
335+ Subtype ( Foo <& ' b u32 >, U )
336+ }
337+ }
338+ } yields {
339+ "Unique; for<?U1> { substitution [?0 := Foo<(&'^0.0 Uint(U32))>], lifetime constraints [\
340+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
341+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \
342+ ] }"
343+ }
344+ }
345+ }
346+
347+ /// Tests that the generalizer recurses into contravariant structs correctly.
348+ #[ test]
349+ fn generalize_contravariant_struct ( ) {
350+ test ! {
351+ program {
352+ #[ variance( Contravariant ) ]
353+ struct Foo <A > { }
354+ }
355+
356+ goal {
357+ forall<' a, ' b> {
358+ exists<U > {
359+ Subtype ( Foo <& ' a u32 >, U ) ,
360+ Subtype ( Foo <& ' b u32 >, U )
361+ }
362+ }
363+ } yields {
364+ // Result should be opposite generalize_covariant_struct result.
365+ "Unique; for<?U1> { substitution [?0 := Foo<(&'^0.0 Uint(U32))>], lifetime constraints [\
366+ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \
367+ InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \
368+ ] }"
369+ }
370+ }
371+ }
372+
373+ /// Tests that the generalizer recurses into invariant structs correctly.
374+ #[ test]
375+ fn generalize_invariant_struct ( ) {
376+ test ! {
377+ program {
378+ #[ variance( Invariant ) ]
379+ struct Foo <A > { }
380+ }
381+
382+ goal {
383+ forall<' a, ' b> {
384+ exists<U > {
385+ Subtype ( Foo <& ' a u32 >, U ) ,
386+ Subtype ( Foo <& ' b u32 >, U )
387+ }
388+ }
389+ } yields[ SolverChoice :: recursive( ) ] {
390+ // Because A is invariant, we require the lifetimes to be equal
391+ "Unique; substitution [?0 := Foo<(&'!1_0 Uint(U32))>], lifetime constraints [ \
392+ InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \
393+ InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \
394+ ]"
395+ } yields[ SolverChoice :: slg_default( ) ] {
396+ "Unique; substitution [?0 := Foo<(&'!1_1 Uint(U32))>], lifetime constraints [ \
397+ InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \
398+ InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \
399+ ]"
400+ }
401+ }
402+ }
403+
404+ /// Tests that the generalizer recurses into slices correctly.
405+ #[ test]
406+ fn generalize_slice ( ) {
407+ test ! {
408+ program {
409+ }
410+
411+ goal {
412+ forall<' a, ' b> {
413+ exists<U > {
414+ Subtype ( [ & ' a u32 ] , U ) ,
415+ Subtype ( [ & ' b u32 ] , U )
416+ }
417+ }
418+ } yields {
419+ // Result should be identical to generalize_covariant_struct result.
420+ "Unique; for<?U1> { substitution [?0 := [(&'^0.0 Uint(U32))]], lifetime constraints [\
421+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
422+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \
423+ ] }"
424+ }
425+ }
426+ }
427+
428+ /// Tests that the generalizer recurses into tuples correctly.
429+ #[ test]
430+ fn generalize_tuple ( ) {
431+ test ! {
432+ program {
433+ }
434+
435+ goal {
436+ forall<' a, ' b> {
437+ exists<U > {
438+ Subtype ( ( & ' a u32 , ) , U ) ,
439+ Subtype ( ( & ' b u32 , ) , U )
440+ }
441+ }
442+ } yields {
443+ // Result should be identical to generalize_covariant_struct result.
444+ "Unique; for<?U1> { substitution [?0 := 1<(&'^0.0 Uint(U32))>], lifetime constraints [\
445+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
446+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \
447+ ] }"
448+ }
449+ }
450+ }
451+
452+ /// Tests that the generalizer recurses into N-tuples correctly.
453+ #[ test]
454+ fn generalize_2tuple ( ) {
455+ test ! {
456+ program {
457+ }
458+
459+ goal {
460+ forall<' a, ' b, ' c, ' d> {
461+ exists<U > {
462+ Subtype ( ( & ' a u32 , & ' c u32 ) , U ) ,
463+ Subtype ( ( & ' b u32 , & ' d u32 ) , U )
464+ }
465+ }
466+ } yields {
467+ "Unique; for<?U1, ?U1> { substitution [?0 := 2<(&'^0.0 Uint(U32)), (&'^0.1 Uint(U32))>], lifetime constraints [\
468+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
469+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, \
470+ InEnvironment { environment: Env([]), goal: '!1_2: '^0.1 }, \
471+ InEnvironment { environment: Env([]), goal: '!1_3: '^0.1 } \
472+ ] }"
473+ }
474+ }
475+ }
476+
477+ /// Tests that the generalizer recurses into arrays correctly.
478+ #[ test]
479+ fn generalize_array ( ) {
480+ test ! {
481+ program {
482+ }
483+
484+ goal {
485+ forall<' a, ' b> {
486+ exists<U > {
487+ Subtype ( [ & ' a u32 ; 16 ] , U ) ,
488+ Subtype ( [ & ' b u32 ; 16 ] , U )
489+ }
490+ }
491+ } yields {
492+ // Result should be identical to generalize_covariant_struct result.
493+ "Unique; for<?U1> { substitution [?0 := [(&'^0.0 Uint(U32)); 16]], lifetime constraints [\
494+ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \
495+ InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \
496+ ] }"
319497 }
320498 }
321499}
0 commit comments