11
11
//! Helper routines for higher-ranked things. See the `doc` module at
12
12
//! the end of the file for details.
13
13
14
- use super :: { CombinedSnapshot , cres, InferCtxt , HigherRankedType } ;
14
+ use super :: { CombinedSnapshot , cres, InferCtxt , HigherRankedType , SkolemizationMap } ;
15
15
use super :: combine:: { Combine , Combineable } ;
16
16
17
17
use middle:: ty:: { mod, Binder } ;
@@ -81,7 +81,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
81
81
82
82
// Presuming type comparison succeeds, we need to check
83
83
// that the skolemized regions do not "leak".
84
- match leak_check ( self . infcx ( ) , & skol_map, snapshot) {
84
+ match self . infcx ( ) . leak_check ( & skol_map, snapshot) {
85
85
Ok ( ( ) ) => { }
86
86
Err ( ( skol_br, tainted_region) ) => {
87
87
if self . a_is_expected ( ) {
@@ -455,11 +455,47 @@ impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
455
455
}
456
456
}
457
457
458
- fn leak_check < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
459
- skol_map : & FnvHashMap < ty:: BoundRegion , ty:: Region > ,
460
- snapshot : & CombinedSnapshot )
461
- -> Result < ( ) , ( ty:: BoundRegion , ty:: Region ) >
458
+ pub fn skolemize_late_bound_regions < ' a , ' tcx , T > ( infcx : & InferCtxt < ' a , ' tcx > ,
459
+ binder : & ty:: Binder < T > ,
460
+ snapshot : & CombinedSnapshot )
461
+ -> ( T , SkolemizationMap )
462
+ where T : TypeFoldable < ' tcx > + Repr < ' tcx >
462
463
{
464
+ /*!
465
+ * Replace all regions bound by `binder` with skolemized regions and
466
+ * return a map indicating which bound-region was replaced with what
467
+ * skolemized region. This is the first step of checking subtyping
468
+ * when higher-ranked things are involved. See `doc.rs` for more details.
469
+ */
470
+
471
+ let ( result, map) = ty:: replace_late_bound_regions ( infcx. tcx , binder, |br, _| {
472
+ infcx. region_vars . new_skolemized ( br, & snapshot. region_vars_snapshot )
473
+ } ) ;
474
+
475
+ debug ! ( "skolemize_bound_regions(binder={}, result={}, map={})" ,
476
+ binder. repr( infcx. tcx) ,
477
+ result. repr( infcx. tcx) ,
478
+ map. repr( infcx. tcx) ) ;
479
+
480
+ ( result, map)
481
+ }
482
+
483
+ pub fn leak_check < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
484
+ skol_map : & SkolemizationMap ,
485
+ snapshot : & CombinedSnapshot )
486
+ -> Result < ( ) , ( ty:: BoundRegion , ty:: Region ) >
487
+ {
488
+ /*!
489
+ * Searches the region constriants created since `snapshot` was started
490
+ * and checks to determine whether any of the skolemized regions created
491
+ * in `skol_map` would "escape" -- meaning that they are related to
492
+ * other regions in some way. If so, the higher-ranked subtyping doesn't
493
+ * hold. See `doc.rs` for more details.
494
+ */
495
+
496
+ debug ! ( "leak_check: skol_map={}" ,
497
+ skol_map. repr( infcx. tcx) ) ;
498
+
463
499
let new_vars = infcx. region_vars_confined_to_snapshot ( snapshot) ;
464
500
for ( & skol_br, & skol) in skol_map. iter ( ) {
465
501
let tainted = infcx. tainted_regions ( snapshot, skol) ;
@@ -475,6 +511,11 @@ fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
475
511
}
476
512
} ;
477
513
514
+ debug ! ( "{} (which replaced {}) is tainted by {}" ,
515
+ skol. repr( infcx. tcx) ,
516
+ skol_br. repr( infcx. tcx) ,
517
+ tainted_region. repr( infcx. tcx) ) ;
518
+
478
519
// A is not as polymorphic as B:
479
520
return Err ( ( skol_br, tainted_region) ) ;
480
521
}
0 commit comments