@@ -29,7 +29,7 @@ use super::{
2929
3030use dep_graph:: { DepKind , DepNodeIndex } ;
3131use hir:: def_id:: DefId ;
32- use infer:: { InferCtxt , InferOk , TypeFreshener } ;
32+ use infer:: { CombinedSnapshot , InferCtxt , InferOk , PlaceholderMap , TypeFreshener } ;
3333use middle:: lang_items;
3434use mir:: interpret:: GlobalId ;
3535use ty:: fast_reject;
@@ -1624,8 +1624,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
16241624 _ => return ,
16251625 }
16261626
1627- let result = self . infcx . probe ( |_| {
1628- self . match_projection_obligation_against_definition_bounds ( obligation)
1627+ let result = self . infcx . probe ( |snapshot| {
1628+ self . match_projection_obligation_against_definition_bounds (
1629+ obligation,
1630+ snapshot,
1631+ )
16291632 } ) ;
16301633
16311634 if result {
@@ -1636,10 +1639,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
16361639 fn match_projection_obligation_against_definition_bounds (
16371640 & mut self ,
16381641 obligation : & TraitObligation < ' tcx > ,
1642+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
16391643 ) -> bool {
16401644 let poly_trait_predicate = self . infcx ( )
16411645 . resolve_type_vars_if_possible ( & obligation. predicate ) ;
1642- let ( placeholder_trait_predicate, _ ) = self . infcx ( )
1646+ let ( placeholder_trait_predicate, placeholder_map ) = self . infcx ( )
16431647 . replace_bound_vars_with_placeholders ( & poly_trait_predicate) ;
16441648 debug ! (
16451649 "match_projection_obligation_against_definition_bounds: \
@@ -1681,6 +1685,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
16811685 obligation,
16821686 bound. clone ( ) ,
16831687 placeholder_trait_predicate. trait_ref . clone ( ) ,
1688+ & placeholder_map,
1689+ snapshot,
16841690 )
16851691 } )
16861692 } ) ;
@@ -1698,6 +1704,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
16981704 obligation,
16991705 bound,
17001706 placeholder_trait_predicate. trait_ref . clone ( ) ,
1707+ & placeholder_map,
1708+ snapshot,
17011709 ) ;
17021710
17031711 assert ! ( result) ;
@@ -1711,12 +1719,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
17111719 obligation : & TraitObligation < ' tcx > ,
17121720 trait_bound : ty:: PolyTraitRef < ' tcx > ,
17131721 placeholder_trait_ref : ty:: TraitRef < ' tcx > ,
1722+ placeholder_map : & PlaceholderMap < ' tcx > ,
1723+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
17141724 ) -> bool {
17151725 debug_assert ! ( !placeholder_trait_ref. has_escaping_bound_vars( ) ) ;
17161726 self . infcx
17171727 . at ( & obligation. cause , obligation. param_env )
17181728 . sup ( ty:: Binder :: dummy ( placeholder_trait_ref) , trait_bound)
17191729 . is_ok ( )
1730+ &&
1731+ self . infcx . leak_check ( false , placeholder_map, snapshot) . is_ok ( )
17201732 }
17211733
17221734 /// Given an obligation like `<SomeTrait for T>`, search the obligations that the caller
@@ -1917,8 +1929,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
19171929 obligation. predicate . def_id ( ) ,
19181930 obligation. predicate . skip_binder ( ) . trait_ref . self_ty ( ) ,
19191931 |impl_def_id| {
1920- self . infcx . probe ( |_ | {
1921- if let Ok ( _substs) = self . match_impl ( impl_def_id, obligation)
1932+ self . infcx . probe ( |snapshot | {
1933+ if let Ok ( _substs) = self . match_impl ( impl_def_id, obligation, snapshot )
19221934 {
19231935 candidates. vec . push ( ImplCandidate ( impl_def_id) ) ;
19241936 }
@@ -2697,9 +2709,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26972709 }
26982710
26992711 fn confirm_projection_candidate ( & mut self , obligation : & TraitObligation < ' tcx > ) {
2700- self . infcx . in_snapshot ( |_ | {
2712+ self . infcx . in_snapshot ( |snapshot | {
27012713 let result =
2702- self . match_projection_obligation_against_definition_bounds ( obligation) ;
2714+ self . match_projection_obligation_against_definition_bounds (
2715+ obligation,
2716+ snapshot,
2717+ ) ;
27032718 assert ! ( result) ;
27042719 } )
27052720 }
@@ -2851,8 +2866,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
28512866
28522867 // First, create the substitutions by matching the impl again,
28532868 // this time not in a probe.
2854- self . infcx . in_snapshot ( |_ | {
2855- let substs = self . rematch_impl ( impl_def_id, obligation) ;
2869+ self . infcx . in_snapshot ( |snapshot | {
2870+ let substs = self . rematch_impl ( impl_def_id, obligation, snapshot ) ;
28562871 debug ! ( "confirm_impl_candidate: substs={:?}" , substs) ;
28572872 let cause = obligation. derived_cause ( ImplDerivedObligation ) ;
28582873 self . vtable_impl (
@@ -3443,8 +3458,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
34433458 & mut self ,
34443459 impl_def_id : DefId ,
34453460 obligation : & TraitObligation < ' tcx > ,
3461+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
34463462 ) -> Normalized < ' tcx , & ' tcx Substs < ' tcx > > {
3447- match self . match_impl ( impl_def_id, obligation) {
3463+ match self . match_impl ( impl_def_id, obligation, snapshot ) {
34483464 Ok ( substs) => substs,
34493465 Err ( ( ) ) => {
34503466 bug ! (
@@ -3460,6 +3476,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
34603476 & mut self ,
34613477 impl_def_id : DefId ,
34623478 obligation : & TraitObligation < ' tcx > ,
3479+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
34633480 ) -> Result < Normalized < ' tcx , & ' tcx Substs < ' tcx > > , ( ) > {
34643481 let impl_trait_ref = self . tcx ( ) . impl_trait_ref ( impl_def_id) . unwrap ( ) ;
34653482
@@ -3470,7 +3487,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
34703487 return Err ( ( ) ) ;
34713488 }
34723489
3473- let ( skol_obligation, _ ) = self . infcx ( )
3490+ let ( skol_obligation, placeholder_map ) = self . infcx ( )
34743491 . replace_bound_vars_with_placeholders ( & obligation. predicate ) ;
34753492 let skol_obligation_trait_ref = skol_obligation. trait_ref ;
34763493
@@ -3502,6 +3519,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
35023519 . map_err ( |e| debug ! ( "match_impl: failed eq_trait_refs due to `{}`" , e) ) ?;
35033520 nested_obligations. extend ( obligations) ;
35043521
3522+ if let Err ( e) = self . infcx . leak_check ( false , & placeholder_map, snapshot) {
3523+ debug ! ( "match_impl: failed leak check due to `{}`" , e) ;
3524+ return Err ( ( ) ) ;
3525+ }
3526+
35053527 debug ! ( "match_impl: success impl_substs={:?}" , impl_substs) ;
35063528 Ok ( Normalized {
35073529 value : impl_substs,
0 commit comments