@@ -25,6 +25,7 @@ use rustc_typeck::middle::infer::combine::Combine;
25
25
use rustc_typeck:: middle:: infer;
26
26
use rustc_typeck:: middle:: infer:: lub:: Lub ;
27
27
use rustc_typeck:: middle:: infer:: glb:: Glb ;
28
+ use rustc_typeck:: middle:: infer:: sub:: Sub ;
28
29
use rustc_typeck:: util:: ppaux:: { ty_to_string, Repr , UserString } ;
29
30
use rustc:: session:: { mod, config} ;
30
31
use syntax:: { abi, ast, ast_map, ast_util} ;
@@ -341,6 +342,11 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
341
342
infer:: TypeTrace :: dummy ( )
342
343
}
343
344
345
+ pub fn sub ( & self ) -> Sub < ' a , ' tcx > {
346
+ let trace = self . dummy_type_trace ( ) ;
347
+ Sub ( self . infcx . combine_fields ( true , trace) )
348
+ }
349
+
344
350
pub fn lub ( & self ) -> Lub < ' a , ' tcx > {
345
351
let trace = self . dummy_type_trace ( ) ;
346
352
Lub ( self . infcx . combine_fields ( true , trace) )
@@ -359,6 +365,33 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
359
365
}
360
366
}
361
367
368
+ /// Checks that `t1 <: t2` is true (this may register additional
369
+ /// region checks).
370
+ pub fn check_sub ( & self , t1 : Ty < ' tcx > , t2 : Ty < ' tcx > ) {
371
+ match self . sub ( ) . tys ( t1, t2) {
372
+ Ok ( _) => { }
373
+ Err ( ref e) => {
374
+ panic ! ( "unexpected error computing sub({},{}): {}" ,
375
+ t1. repr( self . infcx. tcx) ,
376
+ t2. repr( self . infcx. tcx) ,
377
+ ty:: type_err_to_str( self . infcx. tcx, e) ) ;
378
+ }
379
+ }
380
+ }
381
+
382
+ /// Checks that `t1 <: t2` is false (this may register additional
383
+ /// region checks).
384
+ pub fn check_not_sub ( & self , t1 : Ty < ' tcx > , t2 : Ty < ' tcx > ) {
385
+ match self . sub ( ) . tys ( t1, t2) {
386
+ Err ( _) => { }
387
+ Ok ( _) => {
388
+ panic ! ( "unexpected success computing sub({},{})" ,
389
+ t1. repr( self . infcx. tcx) ,
390
+ t2. repr( self . infcx. tcx) ) ;
391
+ }
392
+ }
393
+ }
394
+
362
395
/// Checks that `LUB(t1,t2) == t_lub`
363
396
pub fn check_lub ( & self , t1 : Ty < ' tcx > , t2 : Ty < ' tcx > , t_lub : Ty < ' tcx > ) {
364
397
match self . lub ( ) . tys ( t1, t2) {
@@ -421,6 +454,54 @@ fn contravariant_region_ptr_err() {
421
454
} )
422
455
}
423
456
457
+ #[ test]
458
+ fn sub_free_bound_false ( ) {
459
+ //! Test that:
460
+ //!
461
+ //! fn(&'a int) <: for<'b> fn(&'b int)
462
+ //!
463
+ //! does NOT hold.
464
+
465
+ test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
466
+ let t_rptr_free1 = env. t_rptr_free ( 0 , 1 ) ;
467
+ let t_rptr_bound1 = env. t_rptr_late_bound ( 1 ) ;
468
+ env. check_not_sub ( env. t_fn ( & [ t_rptr_free1] , ty:: mk_int ( ) ) ,
469
+ env. t_fn ( & [ t_rptr_bound1] , ty:: mk_int ( ) ) ) ;
470
+ } )
471
+ }
472
+
473
+ #[ test]
474
+ fn sub_bound_free_true ( ) {
475
+ //! Test that:
476
+ //!
477
+ //! for<'a> fn(&'a int) <: fn(&'b int)
478
+ //!
479
+ //! DOES hold.
480
+
481
+ test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
482
+ let t_rptr_bound1 = env. t_rptr_late_bound ( 1 ) ;
483
+ let t_rptr_free1 = env. t_rptr_free ( 0 , 1 ) ;
484
+ env. check_sub ( env. t_fn ( & [ t_rptr_bound1] , ty:: mk_int ( ) ) ,
485
+ env. t_fn ( & [ t_rptr_free1] , ty:: mk_int ( ) ) ) ;
486
+ } )
487
+ }
488
+
489
+ #[ test]
490
+ fn sub_free_bound_false_infer ( ) {
491
+ //! Test that:
492
+ //!
493
+ //! fn(_#1) <: for<'b> fn(&'b int)
494
+ //!
495
+ //! does NOT hold for any instantiation of `_#1`.
496
+
497
+ test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
498
+ let t_infer1 = env. infcx . next_ty_var ( ) ;
499
+ let t_rptr_bound1 = env. t_rptr_late_bound ( 1 ) ;
500
+ env. check_not_sub ( env. t_fn ( & [ t_infer1] , ty:: mk_int ( ) ) ,
501
+ env. t_fn ( & [ t_rptr_bound1] , ty:: mk_int ( ) ) ) ;
502
+ } )
503
+ }
504
+
424
505
#[ test]
425
506
fn lub_bound_bound ( ) {
426
507
test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
0 commit comments