@@ -44,27 +44,17 @@ use ty::relate::TypeRelation;
44
44
use middle:: lang_items;
45
45
46
46
use rustc_data_structures:: bitvec:: BitVector ;
47
- use rustc_data_structures:: snapshot_vec:: { SnapshotVecDelegate , SnapshotVec } ;
48
47
use std:: iter;
49
48
use std:: cell:: RefCell ;
50
49
use std:: cmp;
51
50
use std:: fmt;
52
- use std:: marker:: PhantomData ;
53
51
use std:: mem;
54
52
use std:: rc:: Rc ;
55
53
use syntax:: abi:: Abi ;
56
54
use hir;
57
55
use lint;
58
56
use util:: nodemap:: { FxHashMap , FxHashSet } ;
59
57
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
- }
68
58
69
59
pub struct SelectionContext < ' cx , ' gcx : ' cx +' tcx , ' tcx : ' cx > {
70
60
infcx : & ' cx InferCtxt < ' cx , ' gcx , ' tcx > ,
@@ -92,8 +82,6 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
92
82
/// would satisfy it. This avoids crippling inference, basically.
93
83
intercrate : Option < IntercrateMode > ,
94
84
95
- inferred_obligations : SnapshotVec < InferredObligationsSnapshotVecDelegate < ' tcx > > ,
96
-
97
85
intercrate_ambiguity_causes : Option < Vec < IntercrateAmbiguityCause > > ,
98
86
99
87
/// Controls whether or not to filter out negative impls when selecting.
@@ -429,7 +417,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
429
417
infcx,
430
418
freshener : infcx. freshener ( ) ,
431
419
intercrate : None ,
432
- inferred_obligations : SnapshotVec :: new ( ) ,
433
420
intercrate_ambiguity_causes : None ,
434
421
allow_negative_impls : false ,
435
422
}
@@ -442,7 +429,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
442
429
infcx,
443
430
freshener : infcx. freshener ( ) ,
444
431
intercrate : Some ( mode) ,
445
- inferred_obligations : SnapshotVec :: new ( ) ,
446
432
intercrate_ambiguity_causes : None ,
447
433
allow_negative_impls : false ,
448
434
}
@@ -455,7 +441,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
455
441
infcx,
456
442
freshener : infcx. freshener ( ) ,
457
443
intercrate : None ,
458
- inferred_obligations : SnapshotVec :: new ( ) ,
459
444
intercrate_ambiguity_causes : None ,
460
445
allow_negative_impls,
461
446
}
@@ -498,8 +483,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
498
483
fn in_snapshot < R , F > ( & mut self , f : F ) -> R
499
484
where F : FnOnce ( & mut Self , & infer:: CombinedSnapshot < ' cx , ' tcx > ) -> R
500
485
{
501
- // The irrefutable nature of the operation means we don't need to snapshot the
502
- // inferred_obligations vector.
503
486
self . infcx . in_snapshot ( |snapshot| f ( self , snapshot) )
504
487
}
505
488
@@ -508,28 +491,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
508
491
fn probe < R , F > ( & mut self , f : F ) -> R
509
492
where F : FnOnce ( & mut Self , & infer:: CombinedSnapshot < ' cx , ' tcx > ) -> R
510
493
{
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) )
515
495
}
516
496
517
497
/// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if
518
498
/// the transaction fails and s.t. old obligations are retained.
519
499
fn commit_if_ok < T , E , F > ( & mut self , f : F ) -> Result < T , E > where
520
500
F : FnOnce ( & mut Self , & infer:: CombinedSnapshot ) -> Result < T , E >
521
501
{
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) )
533
503
}
534
504
535
505
@@ -560,12 +530,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
560
530
let stack = self . push_stack ( TraitObligationStackList :: empty ( ) , obligation) ;
561
531
let ret = match self . candidate_from_obligation ( & stack) ? {
562
532
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) ?)
569
534
} ;
570
535
571
536
// Test whether this is a `()` which was produced by defaulting a
@@ -658,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
658
623
stack : TraitObligationStackList < ' o , ' tcx > ,
659
624
predicates : I )
660
625
-> EvaluationResult
661
- where I : Iterator < Item =& ' a PredicateObligation < ' tcx > > , ' tcx : ' a
626
+ where I : IntoIterator < Item =& ' a PredicateObligation < ' tcx > > , ' tcx : ' a
662
627
{
663
628
let mut result = EvaluatedToOk ;
664
629
for obligation in predicates {
@@ -695,7 +660,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
695
660
// does this code ever run?
696
661
match self . infcx . equality_predicate ( & obligation. cause , obligation. param_env , p) {
697
662
Ok ( InferOk { obligations, .. } ) => {
698
- self . inferred_obligations . extend ( obligations) ;
663
+ self . evaluate_predicates_recursively ( previous_stack , & obligations) ;
699
664
EvaluatedToOk
700
665
} ,
701
666
Err ( _) => EvaluatedToErr
@@ -706,7 +671,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
706
671
// does this code ever run?
707
672
match self . infcx . subtype_predicate ( & obligation. cause , obligation. param_env , p) {
708
673
Some ( Ok ( InferOk { obligations, .. } ) ) => {
709
- self . inferred_obligations . extend ( obligations) ;
674
+ self . evaluate_predicates_recursively ( previous_stack , & obligations) ;
710
675
EvaluatedToOk
711
676
} ,
712
677
Some ( Err ( _) ) => EvaluatedToErr ,
@@ -1553,12 +1518,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1553
1518
-> bool
1554
1519
{
1555
1520
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 ;
1562
1524
}
1563
1525
1564
1526
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> {
2644
2606
} ;
2645
2607
2646
2608
let mut upcast_trait_ref = None ;
2609
+ let mut nested = vec ! [ ] ;
2647
2610
let vtable_base;
2648
2611
2649
2612
{
@@ -2662,7 +2625,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2662
2625
self . commit_if_ok (
2663
2626
|this, _| this. match_poly_trait_ref ( obligation, t) )
2664
2627
{
2665
- Ok ( _) => { upcast_trait_ref = Some ( t) ; false }
2628
+ Ok ( obligations) => {
2629
+ upcast_trait_ref = Some ( t) ;
2630
+ nested. extend ( obligations) ;
2631
+ false
2632
+ }
2666
2633
Err ( _) => { true }
2667
2634
}
2668
2635
} ) ;
@@ -2680,7 +2647,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2680
2647
VtableObjectData {
2681
2648
upcast_trait_ref : upcast_trait_ref. unwrap ( ) ,
2682
2649
vtable_base,
2683
- nested : vec ! [ ]
2650
+ nested,
2684
2651
}
2685
2652
}
2686
2653
@@ -2737,7 +2704,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2737
2704
self . generator_trait_ref_unnormalized ( obligation, closure_def_id, substs) ;
2738
2705
let Normalized {
2739
2706
value : trait_ref,
2740
- obligations
2707
+ mut obligations
2741
2708
} = normalize_with_depth ( self ,
2742
2709
obligation. param_env ,
2743
2710
obligation. cause . clone ( ) ,
@@ -2749,10 +2716,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2749
2716
trait_ref,
2750
2717
obligations) ;
2751
2718
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) ?) ;
2756
2724
2757
2725
Ok ( VtableGeneratorData {
2758
2726
closure_def_id : closure_def_id,
@@ -2798,10 +2766,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2798
2766
trait_ref,
2799
2767
obligations) ;
2800
2768
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) ?) ;
2805
2774
2806
2775
obligations. push ( Obligation :: new (
2807
2776
obligation. cause . clone ( ) ,
@@ -2845,13 +2814,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2845
2814
obligation_param_env : ty:: ParamEnv < ' tcx > ,
2846
2815
obligation_trait_ref : ty:: PolyTraitRef < ' tcx > ,
2847
2816
expected_trait_ref : ty:: PolyTraitRef < ' tcx > )
2848
- -> Result < ( ) , SelectionError < ' tcx > >
2817
+ -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > >
2849
2818
{
2850
2819
let obligation_trait_ref = obligation_trait_ref. clone ( ) ;
2851
2820
self . infcx
2852
2821
. at ( & obligation_cause, obligation_param_env)
2853
2822
. sup ( obligation_trait_ref, expected_trait_ref)
2854
- . map ( |InferOk { obligations, .. } | self . inferred_obligations . extend ( obligations) )
2823
+ . map ( |InferOk { obligations, .. } | obligations)
2855
2824
. map_err ( |e| OutputTypeParameterMismatch ( expected_trait_ref, obligation_trait_ref, e) )
2856
2825
}
2857
2826
@@ -2888,7 +2857,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2888
2857
self . infcx . at ( & obligation. cause , obligation. param_env )
2889
2858
. eq ( target, new_trait)
2890
2859
. map_err ( |_| Unimplemented ) ?;
2891
- self . inferred_obligations . extend ( obligations) ;
2860
+ nested . extend ( obligations) ;
2892
2861
2893
2862
// Register one obligation for 'a: 'b.
2894
2863
let cause = ObligationCause :: new ( obligation. cause . span ,
@@ -2950,7 +2919,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2950
2919
self . infcx . at ( & obligation. cause , obligation. param_env )
2951
2920
. eq ( b, a)
2952
2921
. map_err ( |_| Unimplemented ) ?;
2953
- self . inferred_obligations . extend ( obligations) ;
2922
+ nested . extend ( obligations) ;
2954
2923
}
2955
2924
2956
2925
// Struct<T> -> Struct<U>.
@@ -3014,7 +2983,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3014
2983
self . infcx . at ( & obligation. cause , obligation. param_env )
3015
2984
. eq ( target, new_struct)
3016
2985
. map_err ( |_| Unimplemented ) ?;
3017
- self . inferred_obligations . extend ( obligations) ;
2986
+ nested . extend ( obligations) ;
3018
2987
3019
2988
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
3020
2989
nested. push ( tcx. predicate_for_trait_def (
@@ -3045,7 +3014,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3045
3014
self . infcx . at ( & obligation. cause , obligation. param_env )
3046
3015
. eq ( target, new_tuple)
3047
3016
. map_err ( |_| Unimplemented ) ?;
3048
- self . inferred_obligations . extend ( obligations) ;
3017
+ nested . extend ( obligations) ;
3049
3018
3050
3019
// Construct the nested T: Unsize<U> predicate.
3051
3020
nested. push ( tcx. predicate_for_trait_def (
@@ -3118,7 +3087,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3118
3087
let impl_trait_ref = impl_trait_ref. subst ( self . tcx ( ) ,
3119
3088
impl_substs) ;
3120
3089
3121
- let impl_trait_ref =
3090
+ let Normalized { value : impl_trait_ref, obligations : mut nested_obligations } =
3122
3091
project:: normalize_with_depth ( self ,
3123
3092
obligation. param_env ,
3124
3093
obligation. cause . clone ( ) ,
@@ -3134,12 +3103,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3134
3103
3135
3104
let InferOk { obligations, .. } =
3136
3105
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)
3138
3107
. map_err ( |e| {
3139
3108
debug ! ( "match_impl: failed eq_trait_refs due to `{}`" , e) ;
3140
3109
( )
3141
3110
} ) ?;
3142
- self . inferred_obligations . extend ( obligations) ;
3111
+ nested_obligations . extend ( obligations) ;
3143
3112
3144
3113
if let Err ( e) = self . infcx . leak_check ( false ,
3145
3114
obligation. cause . span ,
@@ -3152,7 +3121,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3152
3121
debug ! ( "match_impl: success impl_substs={:?}" , impl_substs) ;
3153
3122
Ok ( ( Normalized {
3154
3123
value : impl_substs,
3155
- obligations : impl_trait_ref . obligations
3124
+ obligations : nested_obligations
3156
3125
} , skol_map) )
3157
3126
}
3158
3127
@@ -3189,24 +3158,23 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3189
3158
where_clause_trait_ref : ty:: PolyTraitRef < ' tcx > )
3190
3159
-> Result < Vec < PredicateObligation < ' tcx > > , ( ) >
3191
3160
{
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)
3194
3162
}
3195
3163
3196
3164
/// Returns `Ok` if `poly_trait_ref` being true implies that the
3197
3165
/// obligation is satisfied.
3198
3166
fn match_poly_trait_ref ( & mut self ,
3199
3167
obligation : & TraitObligation < ' tcx > ,
3200
3168
poly_trait_ref : ty:: PolyTraitRef < ' tcx > )
3201
- -> Result < ( ) , ( ) >
3169
+ -> Result < Vec < PredicateObligation < ' tcx > > , ( ) >
3202
3170
{
3203
3171
debug ! ( "match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}" ,
3204
3172
obligation,
3205
3173
poly_trait_ref) ;
3206
3174
3207
3175
self . infcx . at ( & obligation. cause , obligation. param_env )
3208
3176
. sup ( obligation. predicate . to_poly_trait_ref ( ) , poly_trait_ref)
3209
- . map ( |InferOk { obligations, .. } | self . inferred_obligations . extend ( obligations) )
3177
+ . map ( |InferOk { obligations, .. } | obligations)
3210
3178
. map_err ( |_| ( ) )
3211
3179
}
3212
3180
0 commit comments