@@ -23,6 +23,7 @@ use middle::subst::Subst;
2323use middle:: ty:: { mod, Ty } ;
2424use middle:: typeck:: infer:: combine:: Combine ;
2525use middle:: typeck:: infer;
26+ use middle:: typeck:: infer:: sub:: Sub ;
2627use middle:: typeck:: infer:: lub:: Lub ;
2728use middle:: typeck:: infer:: glb:: Glb ;
2829use session:: { mod, config} ;
@@ -339,6 +340,11 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
339340 infer:: TypeTrace :: dummy ( )
340341 }
341342
343+ pub fn sub ( & self ) -> Sub < ' a , ' tcx > {
344+ let trace = self . dummy_type_trace ( ) ;
345+ Sub ( self . infcx . combine_fields ( true , trace) )
346+ }
347+
342348 pub fn lub ( & self ) -> Lub < ' a , ' tcx > {
343349 let trace = self . dummy_type_trace ( ) ;
344350 Lub ( self . infcx . combine_fields ( true , trace) )
@@ -357,6 +363,33 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
357363 }
358364 }
359365
366+ /// Checks that `t1 <: t2` is true (this may register additional
367+ /// region checks).
368+ pub fn check_sub ( & self , t1 : Ty < ' tcx > , t2 : Ty < ' tcx > ) {
369+ match self . sub ( ) . tys ( t1, t2) {
370+ Ok ( _) => { }
371+ Err ( ref e) => {
372+ panic ! ( "unexpected error computing sub({},{}): {}" ,
373+ t1. repr( self . infcx. tcx) ,
374+ t2. repr( self . infcx. tcx) ,
375+ ty:: type_err_to_str( self . infcx. tcx, e) ) ;
376+ }
377+ }
378+ }
379+
380+ /// Checks that `t1 <: t2` is false (this may register additional
381+ /// region checks).
382+ pub fn check_not_sub ( & self , t1 : Ty < ' tcx > , t2 : Ty < ' tcx > ) {
383+ match self . sub ( ) . tys ( t1, t2) {
384+ Err ( _) => { }
385+ Ok ( _) => {
386+ panic ! ( "unexpected success computing sub({},{})" ,
387+ t1. repr( self . infcx. tcx) ,
388+ t2. repr( self . infcx. tcx) ) ;
389+ }
390+ }
391+ }
392+
360393 /// Checks that `LUB(t1,t2) == t_lub`
361394 pub fn check_lub ( & self , t1 : Ty < ' tcx > , t2 : Ty < ' tcx > , t_lub : Ty < ' tcx > ) {
362395 match self . lub ( ) . tys ( t1, t2) {
@@ -419,6 +452,54 @@ fn contravariant_region_ptr_err() {
419452 } )
420453}
421454
455+ #[ test]
456+ fn sub_free_bound_false ( ) {
457+ //! Test that:
458+ //!
459+ //! fn(&'a int) <: for<'b> fn(&'b int)
460+ //!
461+ //! does NOT hold.
462+
463+ test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
464+ let t_rptr_free1 = env. t_rptr_free ( 0 , 1 ) ;
465+ let t_rptr_bound1 = env. t_rptr_late_bound ( 1 ) ;
466+ env. check_not_sub ( env. t_fn ( & [ t_rptr_free1] , ty:: mk_int ( ) ) ,
467+ env. t_fn ( & [ t_rptr_bound1] , ty:: mk_int ( ) ) ) ;
468+ } )
469+ }
470+
471+ #[ test]
472+ fn sub_bound_free_true ( ) {
473+ //! Test that:
474+ //!
475+ //! for<'a> fn(&'a int) <: fn(&'b int)
476+ //!
477+ //! DOES hold.
478+
479+ test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
480+ let t_rptr_bound1 = env. t_rptr_late_bound ( 1 ) ;
481+ let t_rptr_free1 = env. t_rptr_free ( 0 , 1 ) ;
482+ env. check_sub ( env. t_fn ( & [ t_rptr_bound1] , ty:: mk_int ( ) ) ,
483+ env. t_fn ( & [ t_rptr_free1] , ty:: mk_int ( ) ) ) ;
484+ } )
485+ }
486+
487+ #[ test]
488+ fn sub_free_bound_false_infer ( ) {
489+ //! Test that:
490+ //!
491+ //! fn(_#1) <: for<'b> fn(&'b int)
492+ //!
493+ //! does NOT hold for any instantiation of `_#1`.
494+
495+ test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
496+ let t_infer1 = env. infcx . next_ty_var ( ) ;
497+ let t_rptr_bound1 = env. t_rptr_late_bound ( 1 ) ;
498+ env. check_not_sub ( env. t_fn ( & [ t_infer1] , ty:: mk_int ( ) ) ,
499+ env. t_fn ( & [ t_rptr_bound1] , ty:: mk_int ( ) ) ) ;
500+ } )
501+ }
502+
422503#[ test]
423504fn lub_bound_bound ( ) {
424505 test_env ( EMPTY_SOURCE_STR , errors ( & [ ] ) , |env| {
0 commit comments