@@ -29,7 +29,7 @@ use super::{
29
29
30
30
use crate :: dep_graph:: { DepKind , DepNodeIndex } ;
31
31
use crate :: hir:: def_id:: DefId ;
32
- use crate :: infer:: { InferCtxt , InferOk , TypeFreshener } ;
32
+ use crate :: infer:: { CombinedSnapshot , InferCtxt , InferOk , PlaceholderMap , TypeFreshener } ;
33
33
use crate :: middle:: lang_items;
34
34
use crate :: mir:: interpret:: GlobalId ;
35
35
use crate :: ty:: fast_reject;
@@ -1667,8 +1667,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1667
1667
_ => return ,
1668
1668
}
1669
1669
1670
- let result = self . infcx . probe ( |_| {
1671
- self . match_projection_obligation_against_definition_bounds ( obligation)
1670
+ let result = self . infcx . probe ( |snapshot| {
1671
+ self . match_projection_obligation_against_definition_bounds (
1672
+ obligation,
1673
+ snapshot,
1674
+ )
1672
1675
} ) ;
1673
1676
1674
1677
if result {
@@ -1679,10 +1682,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1679
1682
fn match_projection_obligation_against_definition_bounds (
1680
1683
& mut self ,
1681
1684
obligation : & TraitObligation < ' tcx > ,
1685
+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
1682
1686
) -> bool {
1683
1687
let poly_trait_predicate = self . infcx ( )
1684
1688
. resolve_type_vars_if_possible ( & obligation. predicate ) ;
1685
- let ( placeholder_trait_predicate, _ ) = self . infcx ( )
1689
+ let ( placeholder_trait_predicate, placeholder_map ) = self . infcx ( )
1686
1690
. replace_bound_vars_with_placeholders ( & poly_trait_predicate) ;
1687
1691
debug ! (
1688
1692
"match_projection_obligation_against_definition_bounds: \
@@ -1724,6 +1728,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1724
1728
obligation,
1725
1729
bound. clone ( ) ,
1726
1730
placeholder_trait_predicate. trait_ref . clone ( ) ,
1731
+ & placeholder_map,
1732
+ snapshot,
1727
1733
)
1728
1734
} )
1729
1735
} ) ;
@@ -1741,6 +1747,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1741
1747
obligation,
1742
1748
bound,
1743
1749
placeholder_trait_predicate. trait_ref . clone ( ) ,
1750
+ & placeholder_map,
1751
+ snapshot,
1744
1752
) ;
1745
1753
1746
1754
assert ! ( result) ;
@@ -1754,12 +1762,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1754
1762
obligation : & TraitObligation < ' tcx > ,
1755
1763
trait_bound : ty:: PolyTraitRef < ' tcx > ,
1756
1764
placeholder_trait_ref : ty:: TraitRef < ' tcx > ,
1765
+ placeholder_map : & PlaceholderMap < ' tcx > ,
1766
+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
1757
1767
) -> bool {
1758
1768
debug_assert ! ( !placeholder_trait_ref. has_escaping_bound_vars( ) ) ;
1759
1769
self . infcx
1760
1770
. at ( & obligation. cause , obligation. param_env )
1761
1771
. sup ( ty:: Binder :: dummy ( placeholder_trait_ref) , trait_bound)
1762
1772
. is_ok ( )
1773
+ &&
1774
+ self . infcx . leak_check ( false , placeholder_map, snapshot) . is_ok ( )
1763
1775
}
1764
1776
1765
1777
/// Given an obligation like `<SomeTrait for T>`, search the obligations that the caller
@@ -1960,8 +1972,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1960
1972
obligation. predicate . def_id ( ) ,
1961
1973
obligation. predicate . skip_binder ( ) . trait_ref . self_ty ( ) ,
1962
1974
|impl_def_id| {
1963
- self . infcx . probe ( |_ | {
1964
- if let Ok ( _substs) = self . match_impl ( impl_def_id, obligation)
1975
+ self . infcx . probe ( |snapshot | {
1976
+ if let Ok ( _substs) = self . match_impl ( impl_def_id, obligation, snapshot )
1965
1977
{
1966
1978
candidates. vec . push ( ImplCandidate ( impl_def_id) ) ;
1967
1979
}
@@ -2758,9 +2770,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2758
2770
}
2759
2771
2760
2772
fn confirm_projection_candidate ( & mut self , obligation : & TraitObligation < ' tcx > ) {
2761
- self . infcx . in_snapshot ( |_ | {
2773
+ self . infcx . in_snapshot ( |snapshot | {
2762
2774
let result =
2763
- self . match_projection_obligation_against_definition_bounds ( obligation) ;
2775
+ self . match_projection_obligation_against_definition_bounds (
2776
+ obligation,
2777
+ snapshot,
2778
+ ) ;
2764
2779
assert ! ( result) ;
2765
2780
} )
2766
2781
}
@@ -2912,8 +2927,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2912
2927
2913
2928
// First, create the substitutions by matching the impl again,
2914
2929
// this time not in a probe.
2915
- self . infcx . in_snapshot ( |_ | {
2916
- let substs = self . rematch_impl ( impl_def_id, obligation) ;
2930
+ self . infcx . in_snapshot ( |snapshot | {
2931
+ let substs = self . rematch_impl ( impl_def_id, obligation, snapshot ) ;
2917
2932
debug ! ( "confirm_impl_candidate: substs={:?}" , substs) ;
2918
2933
let cause = obligation. derived_cause ( ImplDerivedObligation ) ;
2919
2934
self . vtable_impl (
@@ -3504,8 +3519,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3504
3519
& mut self ,
3505
3520
impl_def_id : DefId ,
3506
3521
obligation : & TraitObligation < ' tcx > ,
3522
+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
3507
3523
) -> Normalized < ' tcx , & ' tcx Substs < ' tcx > > {
3508
- match self . match_impl ( impl_def_id, obligation) {
3524
+ match self . match_impl ( impl_def_id, obligation, snapshot ) {
3509
3525
Ok ( substs) => substs,
3510
3526
Err ( ( ) ) => {
3511
3527
bug ! (
@@ -3521,6 +3537,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3521
3537
& mut self ,
3522
3538
impl_def_id : DefId ,
3523
3539
obligation : & TraitObligation < ' tcx > ,
3540
+ snapshot : & CombinedSnapshot < ' _ , ' tcx > ,
3524
3541
) -> Result < Normalized < ' tcx , & ' tcx Substs < ' tcx > > , ( ) > {
3525
3542
let impl_trait_ref = self . tcx ( ) . impl_trait_ref ( impl_def_id) . unwrap ( ) ;
3526
3543
@@ -3531,7 +3548,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3531
3548
return Err ( ( ) ) ;
3532
3549
}
3533
3550
3534
- let ( skol_obligation, _ ) = self . infcx ( )
3551
+ let ( skol_obligation, placeholder_map ) = self . infcx ( )
3535
3552
. replace_bound_vars_with_placeholders ( & obligation. predicate ) ;
3536
3553
let skol_obligation_trait_ref = skol_obligation. trait_ref ;
3537
3554
@@ -3563,6 +3580,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3563
3580
. map_err ( |e| debug ! ( "match_impl: failed eq_trait_refs due to `{}`" , e) ) ?;
3564
3581
nested_obligations. extend ( obligations) ;
3565
3582
3583
+ if let Err ( e) = self . infcx . leak_check ( false , & placeholder_map, snapshot) {
3584
+ debug ! ( "match_impl: failed leak check due to `{}`" , e) ;
3585
+ return Err ( ( ) ) ;
3586
+ }
3587
+
3566
3588
debug ! ( "match_impl: success impl_substs={:?}" , impl_substs) ;
3567
3589
Ok ( Normalized {
3568
3590
value : impl_substs,
0 commit comments