@@ -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 . subtype_predicate ( & obligation. cause , obligation. param_env , p) {
697
662
Some ( Ok ( InferOk { obligations, .. } ) ) => {
698
- self . inferred_obligations . extend ( obligations) ;
663
+ self . evaluate_predicates_recursively ( previous_stack , & obligations) ;
699
664
EvaluatedToOk
700
665
} ,
701
666
Some ( Err ( _) ) => EvaluatedToErr ,
@@ -1542,12 +1507,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1542
1507
-> bool
1543
1508
{
1544
1509
assert ! ( !skol_trait_ref. has_escaping_regions( ) ) ;
1545
- match self . infcx . at ( & obligation. cause , obligation. param_env )
1546
- . sup ( ty:: Binder ( skol_trait_ref) , trait_bound) {
1547
- Ok ( InferOk { obligations, .. } ) => {
1548
- self . inferred_obligations . extend ( obligations) ;
1549
- }
1550
- Err ( _) => { return false ; }
1510
+ if let Err ( _) = self . infcx . at ( & obligation. cause , obligation. param_env )
1511
+ . sup ( ty:: Binder ( skol_trait_ref) , trait_bound) {
1512
+ return false ;
1551
1513
}
1552
1514
1553
1515
self . infcx . leak_check ( false , obligation. cause . span , skol_map, snapshot) . is_ok ( )
@@ -2633,6 +2595,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2633
2595
} ;
2634
2596
2635
2597
let mut upcast_trait_ref = None ;
2598
+ let mut nested = vec ! [ ] ;
2636
2599
let vtable_base;
2637
2600
2638
2601
{
@@ -2651,7 +2614,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2651
2614
self . commit_if_ok (
2652
2615
|this, _| this. match_poly_trait_ref ( obligation, t) )
2653
2616
{
2654
- Ok ( _) => { upcast_trait_ref = Some ( t) ; false }
2617
+ Ok ( obligations) => {
2618
+ upcast_trait_ref = Some ( t) ;
2619
+ nested. extend ( obligations) ;
2620
+ false
2621
+ }
2655
2622
Err ( _) => { true }
2656
2623
}
2657
2624
} ) ;
@@ -2669,7 +2636,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2669
2636
VtableObjectData {
2670
2637
upcast_trait_ref : upcast_trait_ref. unwrap ( ) ,
2671
2638
vtable_base,
2672
- nested : vec ! [ ]
2639
+ nested,
2673
2640
}
2674
2641
}
2675
2642
@@ -2726,7 +2693,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2726
2693
self . generator_trait_ref_unnormalized ( obligation, closure_def_id, substs) ;
2727
2694
let Normalized {
2728
2695
value : trait_ref,
2729
- obligations
2696
+ mut obligations
2730
2697
} = normalize_with_depth ( self ,
2731
2698
obligation. param_env ,
2732
2699
obligation. cause . clone ( ) ,
@@ -2738,10 +2705,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2738
2705
trait_ref,
2739
2706
obligations) ;
2740
2707
2741
- self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2742
- obligation. param_env ,
2743
- obligation. predicate . to_poly_trait_ref ( ) ,
2744
- trait_ref) ?;
2708
+ obligations. extend (
2709
+ self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2710
+ obligation. param_env ,
2711
+ obligation. predicate . to_poly_trait_ref ( ) ,
2712
+ trait_ref) ?) ;
2745
2713
2746
2714
Ok ( VtableGeneratorData {
2747
2715
closure_def_id : closure_def_id,
@@ -2787,10 +2755,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2787
2755
trait_ref,
2788
2756
obligations) ;
2789
2757
2790
- self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2791
- obligation. param_env ,
2792
- obligation. predicate . to_poly_trait_ref ( ) ,
2793
- trait_ref) ?;
2758
+ obligations. extend (
2759
+ self . confirm_poly_trait_refs ( obligation. cause . clone ( ) ,
2760
+ obligation. param_env ,
2761
+ obligation. predicate . to_poly_trait_ref ( ) ,
2762
+ trait_ref) ?) ;
2794
2763
2795
2764
obligations. push ( Obligation :: new (
2796
2765
obligation. cause . clone ( ) ,
@@ -2834,13 +2803,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2834
2803
obligation_param_env : ty:: ParamEnv < ' tcx > ,
2835
2804
obligation_trait_ref : ty:: PolyTraitRef < ' tcx > ,
2836
2805
expected_trait_ref : ty:: PolyTraitRef < ' tcx > )
2837
- -> Result < ( ) , SelectionError < ' tcx > >
2806
+ -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > >
2838
2807
{
2839
2808
let obligation_trait_ref = obligation_trait_ref. clone ( ) ;
2840
2809
self . infcx
2841
2810
. at ( & obligation_cause, obligation_param_env)
2842
2811
. sup ( obligation_trait_ref, expected_trait_ref)
2843
- . map ( |InferOk { obligations, .. } | self . inferred_obligations . extend ( obligations) )
2812
+ . map ( |InferOk { obligations, .. } | obligations)
2844
2813
. map_err ( |e| OutputTypeParameterMismatch ( expected_trait_ref, obligation_trait_ref, e) )
2845
2814
}
2846
2815
@@ -2877,7 +2846,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2877
2846
self . infcx . at ( & obligation. cause , obligation. param_env )
2878
2847
. eq ( target, new_trait)
2879
2848
. map_err ( |_| Unimplemented ) ?;
2880
- self . inferred_obligations . extend ( obligations) ;
2849
+ nested . extend ( obligations) ;
2881
2850
2882
2851
// Register one obligation for 'a: 'b.
2883
2852
let cause = ObligationCause :: new ( obligation. cause . span ,
@@ -2939,7 +2908,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
2939
2908
self . infcx . at ( & obligation. cause , obligation. param_env )
2940
2909
. eq ( b, a)
2941
2910
. map_err ( |_| Unimplemented ) ?;
2942
- self . inferred_obligations . extend ( obligations) ;
2911
+ nested . extend ( obligations) ;
2943
2912
}
2944
2913
2945
2914
// Struct<T> -> Struct<U>.
@@ -3003,7 +2972,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3003
2972
self . infcx . at ( & obligation. cause , obligation. param_env )
3004
2973
. eq ( target, new_struct)
3005
2974
. map_err ( |_| Unimplemented ) ?;
3006
- self . inferred_obligations . extend ( obligations) ;
2975
+ nested . extend ( obligations) ;
3007
2976
3008
2977
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
3009
2978
nested. push ( tcx. predicate_for_trait_def (
@@ -3034,7 +3003,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3034
3003
self . infcx . at ( & obligation. cause , obligation. param_env )
3035
3004
. eq ( target, new_tuple)
3036
3005
. map_err ( |_| Unimplemented ) ?;
3037
- self . inferred_obligations . extend ( obligations) ;
3006
+ nested . extend ( obligations) ;
3038
3007
3039
3008
// Construct the nested T: Unsize<U> predicate.
3040
3009
nested. push ( tcx. predicate_for_trait_def (
@@ -3107,7 +3076,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3107
3076
let impl_trait_ref = impl_trait_ref. subst ( self . tcx ( ) ,
3108
3077
impl_substs) ;
3109
3078
3110
- let impl_trait_ref =
3079
+ let Normalized { value : impl_trait_ref, obligations : mut nested_obligations } =
3111
3080
project:: normalize_with_depth ( self ,
3112
3081
obligation. param_env ,
3113
3082
obligation. cause . clone ( ) ,
@@ -3123,12 +3092,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3123
3092
3124
3093
let InferOk { obligations, .. } =
3125
3094
self . infcx . at ( & obligation. cause , obligation. param_env )
3126
- . eq ( skol_obligation_trait_ref, impl_trait_ref. value )
3095
+ . eq ( skol_obligation_trait_ref, impl_trait_ref)
3127
3096
. map_err ( |e| {
3128
3097
debug ! ( "match_impl: failed eq_trait_refs due to `{}`" , e) ;
3129
3098
( )
3130
3099
} ) ?;
3131
- self . inferred_obligations . extend ( obligations) ;
3100
+ nested_obligations . extend ( obligations) ;
3132
3101
3133
3102
if let Err ( e) = self . infcx . leak_check ( false ,
3134
3103
obligation. cause . span ,
@@ -3141,7 +3110,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3141
3110
debug ! ( "match_impl: success impl_substs={:?}" , impl_substs) ;
3142
3111
Ok ( ( Normalized {
3143
3112
value : impl_substs,
3144
- obligations : impl_trait_ref . obligations
3113
+ obligations : nested_obligations
3145
3114
} , skol_map) )
3146
3115
}
3147
3116
@@ -3178,24 +3147,23 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
3178
3147
where_clause_trait_ref : ty:: PolyTraitRef < ' tcx > )
3179
3148
-> Result < Vec < PredicateObligation < ' tcx > > , ( ) >
3180
3149
{
3181
- self . match_poly_trait_ref ( obligation, where_clause_trait_ref) ?;
3182
- Ok ( Vec :: new ( ) )
3150
+ self . match_poly_trait_ref ( obligation, where_clause_trait_ref)
3183
3151
}
3184
3152
3185
3153
/// Returns `Ok` if `poly_trait_ref` being true implies that the
3186
3154
/// obligation is satisfied.
3187
3155
fn match_poly_trait_ref ( & mut self ,
3188
3156
obligation : & TraitObligation < ' tcx > ,
3189
3157
poly_trait_ref : ty:: PolyTraitRef < ' tcx > )
3190
- -> Result < ( ) , ( ) >
3158
+ -> Result < Vec < PredicateObligation < ' tcx > > , ( ) >
3191
3159
{
3192
3160
debug ! ( "match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}" ,
3193
3161
obligation,
3194
3162
poly_trait_ref) ;
3195
3163
3196
3164
self . infcx . at ( & obligation. cause , obligation. param_env )
3197
3165
. sup ( obligation. predicate . to_poly_trait_ref ( ) , poly_trait_ref)
3198
- . map ( |InferOk { obligations, .. } | self . inferred_obligations . extend ( obligations) )
3166
+ . map ( |InferOk { obligations, .. } | obligations)
3199
3167
. map_err ( |_| ( ) )
3200
3168
}
3201
3169
0 commit comments