@@ -137,8 +137,7 @@ fn generalize() {
137
137
}
138
138
}
139
139
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.
142
141
#[ test]
143
142
fn multi_lifetime ( ) {
144
143
test ! {
@@ -168,7 +167,7 @@ fn multi_lifetime() {
168
167
}
169
168
}
170
169
171
- /// Tests that the generalizer generalizes lifetimes within a covariant struct .
170
+ /// Tests that we handle variance for covariant structs correctly .
172
171
#[ test]
173
172
fn multi_lifetime_covariant_struct ( ) {
174
173
test ! {
@@ -193,8 +192,7 @@ fn multi_lifetime_covariant_struct() {
193
192
}
194
193
}
195
194
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.
198
196
#[ test]
199
197
fn multi_lifetime_contravariant_struct ( ) {
200
198
test ! {
@@ -219,7 +217,7 @@ fn multi_lifetime_contravariant_struct() {
219
217
}
220
218
}
221
219
222
- /// Tests that the generalizer generalizes lifetimes within a invariant struct .
220
+ /// Tests that we handle variance for invariant structs correctly .
223
221
#[ test]
224
222
fn multi_lifetime_invariant_struct ( ) {
225
223
test ! {
@@ -251,7 +249,7 @@ fn multi_lifetime_invariant_struct() {
251
249
}
252
250
}
253
251
254
- /// Tests that the generalizer generalizes lifetimes within slices correctly.
252
+ /// Tests that we handle variance for slices correctly.
255
253
#[ test]
256
254
fn multi_lifetime_slice ( ) {
257
255
test ! {
@@ -274,7 +272,7 @@ fn multi_lifetime_slice() {
274
272
}
275
273
}
276
274
277
- /// Tests that the generalizer generalizes lifetimes within tuples correctly.
275
+ /// Tests that we handle variance for tuples correctly.
278
276
#[ test]
279
277
fn multi_lifetime_tuple ( ) {
280
278
test ! {
@@ -297,7 +295,7 @@ fn multi_lifetime_tuple() {
297
295
}
298
296
}
299
297
300
- /// Tests that the generalizer generalizes lifetimes within tuples correctly.
298
+ /// Tests that we handle variance for arrays correctly.
301
299
#[ test]
302
300
fn multi_lifetime_array ( ) {
303
301
test ! {
@@ -314,8 +312,188 @@ fn multi_lifetime_array() {
314
312
} yields {
315
313
// Result should be identical to multi_lifetime result.
316
314
"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
+ ] }"
319
497
}
320
498
}
321
499
}
0 commit comments