@@ -44,27 +44,17 @@ use ty::relate::TypeRelation;
4444use middle:: lang_items;
4545
4646use rustc_data_structures:: bitvec:: BitVector ;
47- use rustc_data_structures:: snapshot_vec:: { SnapshotVecDelegate , SnapshotVec } ;
4847use std:: iter;
4948use std:: cell:: RefCell ;
5049use std:: cmp;
5150use std:: fmt;
52- use std:: marker:: PhantomData ;
5351use std:: mem;
5452use std:: rc:: Rc ;
5553use syntax:: abi:: Abi ;
5654use hir;
5755use lint;
5856use util:: nodemap:: { FxHashMap , FxHashSet } ;
5957
60- struct InferredObligationsSnapshotVecDelegate < ' tcx > {
61- phantom : PhantomData < & ' tcx i32 > ,
62- }
63- impl < ' tcx > SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate < ' tcx > {
64- type Value = PredicateObligation < ' tcx > ;
65- type Undo = ( ) ;
66- fn reverse ( _: & mut Vec < Self :: Value > , _: Self :: Undo ) { }
67- }
6858
6959pub struct SelectionContext < ' cx , ' gcx : ' cx +' tcx , ' tcx : ' cx > {
7060 infcx : & ' cx InferCtxt < ' cx , ' gcx , ' tcx > ,
@@ -92,8 +82,6 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
9282 /// would satisfy it. This avoids crippling inference, basically.
9383 intercrate : Option < IntercrateMode > ,
9484
95- inferred_obligations : SnapshotVec < InferredObligationsSnapshotVecDelegate < ' tcx > > ,
96-
9785 intercrate_ambiguity_causes : Option < Vec < IntercrateAmbiguityCause > > ,
9886
9987 /// Controls whether or not to filter out negative impls when selecting.
@@ -429,7 +417,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
429417 infcx,
430418 freshener : infcx. freshener ( ) ,
431419 intercrate : None ,
432- inferred_obligations : SnapshotVec :: new ( ) ,
433420 intercrate_ambiguity_causes : None ,
434421 allow_negative_impls : false ,
435422 }
@@ -442,7 +429,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
442429 infcx,
443430 freshener : infcx. freshener ( ) ,
444431 intercrate : Some ( mode) ,
445- inferred_obligations : SnapshotVec :: new ( ) ,
446432 intercrate_ambiguity_causes : None ,
447433 allow_negative_impls : false ,
448434 }
@@ -455,7 +441,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
455441 infcx,
456442 freshener : infcx. freshener ( ) ,
457443 intercrate : None ,
458- inferred_obligations : SnapshotVec :: new ( ) ,
459444 intercrate_ambiguity_causes : None ,
460445 allow_negative_impls,
461446 }
@@ -498,8 +483,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
498483 fn in_snapshot < R , F > ( & mut self , f : F ) -> R
499484 where F : FnOnce ( & mut Self , & infer:: CombinedSnapshot < ' cx , ' tcx > ) -> R
500485 {
501- // The irrefutable nature of the operation means we don't need to snapshot the
502- // inferred_obligations vector.
503486 self . infcx . in_snapshot ( |snapshot| f ( self , snapshot) )
504487 }
505488
@@ -508,28 +491,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
508491 fn probe < R , F > ( & mut self , f : F ) -> R
509492 where F : FnOnce ( & mut Self , & infer:: CombinedSnapshot < ' cx , ' tcx > ) -> R
510493 {
511- let inferred_obligations_snapshot = self . inferred_obligations . start_snapshot ( ) ;
512- let result = self . infcx . probe ( |snapshot| f ( self , snapshot) ) ;
513- self . inferred_obligations . rollback_to ( inferred_obligations_snapshot) ;
514- result
494+ self . infcx . probe ( |snapshot| f ( self , snapshot) )
515495 }
516496
517497 /// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if
518498 /// the transaction fails and s.t. old obligations are retained.
519499 fn commit_if_ok < T , E , F > ( & mut self , f : F ) -> Result < T , E > where
520500 F : FnOnce ( & mut Self , & infer:: CombinedSnapshot ) -> Result < T , E >
521501 {
522- let inferred_obligations_snapshot = self . inferred_obligations . start_snapshot ( ) ;
523- match self . infcx . commit_if_ok ( |snapshot| f ( self , snapshot) ) {
524- Ok ( ok) => {
525- self . inferred_obligations . commit ( inferred_obligations_snapshot) ;
526- Ok ( ok)
527- } ,
528- Err ( err) => {
529- self . inferred_obligations . rollback_to ( inferred_obligations_snapshot) ;
530- Err ( err)
531- }
532- }
502+ self . infcx . commit_if_ok ( |snapshot| f ( self , snapshot) )
533503 }
534504
535505
@@ -560,12 +530,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
560530 let stack = self . push_stack ( TraitObligationStackList :: empty ( ) , obligation) ;
561531 let ret = match self . candidate_from_obligation ( & stack) ? {
562532 None => None ,
563- Some ( candidate) => {
564- let mut candidate = self . confirm_candidate ( obligation, candidate) ?;
565- let inferred_obligations = ( * self . inferred_obligations ) . into_iter ( ) . cloned ( ) ;
566- candidate. nested_obligations_mut ( ) . extend ( inferred_obligations) ;
567- Some ( candidate)
568- } ,
533+ Some ( candidate) => Some ( self . confirm_candidate ( obligation, candidate) ?)
569534 } ;
570535
571536 // Test whether this is a `()` which was produced by defaulting a
@@ -658,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
658623 stack : TraitObligationStackList < ' o , ' tcx > ,
659624 predicates : I )
660625 -> EvaluationResult
661- where I : Iterator < Item =& ' a PredicateObligation < ' tcx > > , ' tcx : ' a
626+ where I : IntoIterator < Item =& ' a PredicateObligation < ' tcx > > , ' tcx : ' a
662627 {
663628 let mut result = EvaluatedToOk ;
664629 for obligation in predicates {
@@ -695,7 +660,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
695660 // does this code ever run?
696661 match self . infcx . equality_predicate ( & obligation. cause , obligation. param_env , p) {
697662 Ok ( InferOk { obligations, .. } ) => {
698- self . inferred_obligations . extend ( obligations) ;
663+ self . evaluate_predicates_recursively ( previous_stack , & obligations) ;
699664 EvaluatedToOk
700665 } ,
701666 Err ( _) => EvaluatedToErr
@@ -706,7 +671,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
706671 // does this code ever run?
707672 match self . infcx . subtype_predicate ( & obligation. cause , obligation. param_env , p) {
708673 Some ( Ok ( InferOk { obligations, .. } ) ) => {
709- self . inferred_obligations . extend ( obligations) ;
674+ self . evaluate_predicates_recursively ( previous_stack , & obligations) ;
710675 EvaluatedToOk
711676 } ,
712677 Some ( Err ( _) ) => EvaluatedToErr ,
@@ -1553,12 +1518,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
15531518 -> bool
15541519 {
15551520 assert ! ( !skol_trait_ref. has_escaping_regions( ) ) ;
1556- match self . infcx . at ( & obligation. cause , obligation. param_env )
1557- . sup ( ty:: Binder ( skol_trait_ref) , trait_bound) {
1558- Ok ( InferOk { obligations, .. } ) => {
1559- self . inferred_obligations . extend ( obligations) ;
1560- }
1561- Err ( _) => { return false ; }
1521+ if let Err ( _) = self . infcx . at ( & obligation. cause , obligation. param_env )
1522+ . sup ( ty:: Binder ( skol_trait_ref) , trait_bound) {
1523+ return false ;
15621524 }
15631525
15641526 self . infcx . leak_check ( false , obligation. cause . span , skol_map, snapshot) . is_ok ( )
@@ -2644,6 +2606,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26442606 } ;
26452607
26462608 let mut upcast_trait_ref = None ;
2609+ let mut nested = vec ! [ ] ;
26472610 let vtable_base;
26482611
26492612 {
@@ -2662,7 +2625,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26622625 self . commit_if_ok (
26632626 |this, _| this. match_poly_trait_ref ( obligation, t) )
26642627 {
2665- Ok ( _) => { upcast_trait_ref = Some ( t) ; false }
2628+ Ok ( obligations) => {
2629+ upcast_trait_ref = Some ( t) ;
2630+ nested. extend ( obligations) ;
2631+ false
2632+ }
26662633 Err ( _) => { true }
26672634 }
26682635 } ) ;
@@ -2680,7 +2647,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
26802647 VtableObjectData {
26812648 upcast_trait_ref : upcast_trait_ref. unwrap ( ) ,
26822649 vtable_base,
2683- nested : vec ! [ ]
2650+ nested,
26842651 }
26852652 }
26862653
@@ -2737,7 +2704,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
27372704 self . generator_trait_ref_unnormalized ( obligation, closure_def_id, substs) ;
27382705 let Normalized {
27392706 value : trait_ref,
2740- obligations
2707+ mut obligations
27412708 } = normalize_with_depth ( self ,
27422709 obligation. param_env ,
27432710 obligation. cause . clone ( ) ,
@@ -2749,10 +2716,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
27492716 trait_ref,
27502717 obligations) ;
27512718
2752- self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2753- obligation. param_env ,
2754- obligation. predicate . to_poly_trait_ref ( ) ,
2755- trait_ref) ?;
2719+ obligations. extend (
2720+ self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2721+ obligation. param_env ,
2722+ obligation. predicate . to_poly_trait_ref ( ) ,
2723+ trait_ref) ?) ;
27562724
27572725 Ok ( VtableGeneratorData {
27582726 closure_def_id : closure_def_id,
@@ -2798,10 +2766,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
27982766 trait_ref,
27992767 obligations) ;
28002768
2801- self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2802- obligation. param_env ,
2803- obligation. predicate . to_poly_trait_ref ( ) ,
2804- trait_ref) ?;
2769+ obligations. extend (
2770+ self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2771+ obligation. param_env ,
2772+ obligation. predicate . to_poly_trait_ref ( ) ,
2773+ trait_ref) ?) ;
28052774
28062775 obligations. push ( Obligation :: new (
28072776 obligation. cause . clone ( ) ,
@@ -2845,13 +2814,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
28452814 obligation_param_env : ty:: ParamEnv < ' tcx > ,
28462815 obligation_trait_ref : ty:: PolyTraitRef < ' tcx > ,
28472816 expected_trait_ref : ty:: PolyTraitRef < ' tcx > )
2848- -> Result < ( ) , SelectionError < ' tcx > >
2817+ -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > >
28492818 {
28502819 let obligation_trait_ref = obligation_trait_ref. clone ( ) ;
28512820 self . infcx
28522821 . at ( & obligation_cause, obligation_param_env)
28532822 . sup ( obligation_trait_ref, expected_trait_ref)
2854- . map ( |InferOk { obligations, .. } | self . inferred_obligations . extend ( obligations) )
2823+ . map ( |InferOk { obligations, .. } | obligations)
28552824 . map_err ( |e| OutputTypeParameterMismatch ( expected_trait_ref, obligation_trait_ref, e) )
28562825 }
28572826
@@ -2888,7 +2857,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
28882857 self . infcx . at ( & obligation. cause , obligation. param_env )
28892858 . eq ( target, new_trait)
28902859 . map_err ( |_| Unimplemented ) ?;
2891- self . inferred_obligations . extend ( obligations) ;
2860+ nested . extend ( obligations) ;
28922861
28932862 // Register one obligation for 'a: 'b.
28942863 let cause = ObligationCause :: new ( obligation. cause . span ,
@@ -2950,7 +2919,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
29502919 self . infcx . at ( & obligation. cause , obligation. param_env )
29512920 . eq ( b, a)
29522921 . map_err ( |_| Unimplemented ) ?;
2953- self . inferred_obligations . extend ( obligations) ;
2922+ nested . extend ( obligations) ;
29542923 }
29552924
29562925 // Struct<T> -> Struct<U>.
@@ -3014,7 +2983,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
30142983 self . infcx . at ( & obligation. cause , obligation. param_env )
30152984 . eq ( target, new_struct)
30162985 . map_err ( |_| Unimplemented ) ?;
3017- self . inferred_obligations . extend ( obligations) ;
2986+ nested . extend ( obligations) ;
30182987
30192988 // Construct the nested Field<T>: Unsize<Field<U>> predicate.
30202989 nested. push ( tcx. predicate_for_trait_def (
@@ -3045,7 +3014,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
30453014 self . infcx . at ( & obligation. cause , obligation. param_env )
30463015 . eq ( target, new_tuple)
30473016 . map_err ( |_| Unimplemented ) ?;
3048- self . inferred_obligations . extend ( obligations) ;
3017+ nested . extend ( obligations) ;
30493018
30503019 // Construct the nested T: Unsize<U> predicate.
30513020 nested. push ( tcx. predicate_for_trait_def (
@@ -3118,7 +3087,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31183087 let impl_trait_ref = impl_trait_ref. subst ( self . tcx ( ) ,
31193088 impl_substs) ;
31203089
3121- let impl_trait_ref =
3090+ let Normalized { value : impl_trait_ref, obligations : mut nested_obligations } =
31223091 project:: normalize_with_depth ( self ,
31233092 obligation. param_env ,
31243093 obligation. cause . clone ( ) ,
@@ -3134,12 +3103,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31343103
31353104 let InferOk { obligations, .. } =
31363105 self . infcx . at ( & obligation. cause , obligation. param_env )
3137- . eq ( skol_obligation_trait_ref, impl_trait_ref. value )
3106+ . eq ( skol_obligation_trait_ref, impl_trait_ref)
31383107 . map_err ( |e| {
31393108 debug ! ( "match_impl: failed eq_trait_refs due to `{}`" , e) ;
31403109 ( )
31413110 } ) ?;
3142- self . inferred_obligations . extend ( obligations) ;
3111+ nested_obligations . extend ( obligations) ;
31433112
31443113 if let Err ( e) = self . infcx . leak_check ( false ,
31453114 obligation. cause . span ,
@@ -3152,7 +3121,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31523121 debug ! ( "match_impl: success impl_substs={:?}" , impl_substs) ;
31533122 Ok ( ( Normalized {
31543123 value : impl_substs,
3155- obligations : impl_trait_ref . obligations
3124+ obligations : nested_obligations
31563125 } , skol_map) )
31573126 }
31583127
@@ -3189,24 +3158,23 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
31893158 where_clause_trait_ref : ty:: PolyTraitRef < ' tcx > )
31903159 -> Result < Vec < PredicateObligation < ' tcx > > , ( ) >
31913160 {
3192- self . match_poly_trait_ref ( obligation, where_clause_trait_ref) ?;
3193- Ok ( Vec :: new ( ) )
3161+ self . match_poly_trait_ref ( obligation, where_clause_trait_ref)
31943162 }
31953163
31963164 /// Returns `Ok` if `poly_trait_ref` being true implies that the
31973165 /// obligation is satisfied.
31983166 fn match_poly_trait_ref ( & mut self ,
31993167 obligation : & TraitObligation < ' tcx > ,
32003168 poly_trait_ref : ty:: PolyTraitRef < ' tcx > )
3201- -> Result < ( ) , ( ) >
3169+ -> Result < Vec < PredicateObligation < ' tcx > > , ( ) >
32023170 {
32033171 debug ! ( "match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}" ,
32043172 obligation,
32053173 poly_trait_ref) ;
32063174
32073175 self . infcx . at ( & obligation. cause , obligation. param_env )
32083176 . sup ( obligation. predicate . to_poly_trait_ref ( ) , poly_trait_ref)
3209- . map ( |InferOk { obligations, .. } | self . inferred_obligations . extend ( obligations) )
3177+ . map ( |InferOk { obligations, .. } | obligations)
32103178 . map_err ( |_| ( ) )
32113179 }
32123180
0 commit comments