11
11
use dep_graph:: DepGraph ;
12
12
use infer:: { InferCtxt , InferOk } ;
13
13
use ty:: { self , Ty , TypeFoldable , ToPolyTraitRef , TyCtxt , ToPredicate } ;
14
- use ty:: subst:: Subst ;
15
14
use rustc_data_structures:: obligation_forest:: { ObligationForest , Error } ;
16
15
use rustc_data_structures:: obligation_forest:: { ForestObligation , ObligationProcessor } ;
17
16
use std:: marker:: PhantomData ;
18
- use std:: mem;
19
17
use syntax:: ast;
20
18
use util:: nodemap:: { FxHashSet , NodeMap } ;
21
19
use hir:: def_id:: DefId ;
22
20
23
21
use super :: CodeAmbiguity ;
24
22
use super :: CodeProjectionError ;
25
23
use super :: CodeSelectionError ;
26
- use super :: { FulfillmentError , FulfillmentErrorCode , SelectionError } ;
27
- use super :: { ObligationCause , BuiltinDerivedObligation } ;
28
- use super :: { PredicateObligation , TraitObligation , Obligation } ;
24
+ use super :: { FulfillmentError , FulfillmentErrorCode } ;
25
+ use super :: { ObligationCause , PredicateObligation , Obligation } ;
29
26
use super :: project;
30
27
use super :: select:: SelectionContext ;
31
28
use super :: Unimplemented ;
@@ -82,10 +79,6 @@ pub struct FulfillmentContext<'tcx> {
82
79
// obligations (otherwise, it's easy to fail to walk to a
83
80
// particular node-id).
84
81
region_obligations : NodeMap < Vec < RegionObligation < ' tcx > > > ,
85
-
86
- // A list of obligations that need to be deferred to
87
- // a later time for them to be properly fulfilled.
88
- deferred_obligations : Vec < DeferredObligation < ' tcx > > ,
89
82
}
90
83
91
84
#[ derive( Clone ) ]
@@ -101,100 +94,12 @@ pub struct PendingPredicateObligation<'tcx> {
101
94
pub stalled_on : Vec < Ty < ' tcx > > ,
102
95
}
103
96
104
- /// An obligation which cannot be fulfilled in the context
105
- /// it was registered in, such as auto trait obligations on
106
- /// `impl Trait`, which require the concrete type to be
107
- /// available, only guaranteed after finishing type-checking.
108
- #[ derive( Clone , Debug ) ]
109
- pub struct DeferredObligation < ' tcx > {
110
- pub predicate : ty:: PolyTraitPredicate < ' tcx > ,
111
- pub cause : ObligationCause < ' tcx >
112
- }
113
-
114
- impl < ' a , ' gcx , ' tcx > DeferredObligation < ' tcx > {
115
- /// If possible, create a `DeferredObligation` from
116
- /// a trait predicate which had failed selection,
117
- /// but could succeed later.
118
- pub fn from_select_error ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
119
- obligation : & TraitObligation < ' tcx > ,
120
- selection_err : & SelectionError < ' tcx > )
121
- -> Option < DeferredObligation < ' tcx > > {
122
- if let Unimplemented = * selection_err {
123
- if DeferredObligation :: must_defer ( tcx, & obligation. predicate ) {
124
- return Some ( DeferredObligation {
125
- predicate : obligation. predicate . clone ( ) ,
126
- cause : obligation. cause . clone ( )
127
- } ) ;
128
- }
129
- }
130
-
131
- None
132
- }
133
-
134
- /// Returns true if the given trait predicate can be
135
- /// fulfilled at a later time.
136
- pub fn must_defer ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
137
- predicate : & ty:: PolyTraitPredicate < ' tcx > )
138
- -> bool {
139
- // Auto trait obligations on `impl Trait`.
140
- if tcx. trait_has_default_impl ( predicate. def_id ( ) ) {
141
- let substs = predicate. skip_binder ( ) . trait_ref . substs ;
142
- if substs. types ( ) . count ( ) == 1 && substs. regions ( ) . next ( ) . is_none ( ) {
143
- if let ty:: TyAnon ( ..) = predicate. skip_binder ( ) . self_ty ( ) . sty {
144
- return true ;
145
- }
146
- }
147
- }
148
-
149
- false
150
- }
151
-
152
- /// If possible, return the nested obligations required
153
- /// to fulfill this obligation.
154
- pub fn try_select ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > )
155
- -> Option < Vec < PredicateObligation < ' tcx > > > {
156
- if let ty:: TyAnon ( def_id, substs) = self . predicate . skip_binder ( ) . self_ty ( ) . sty {
157
- let ty = if def_id. is_local ( ) {
158
- tcx. maps . ty . borrow ( ) . get ( & def_id) . cloned ( )
159
- } else {
160
- Some ( tcx. item_type ( def_id) )
161
- } ;
162
- // We can resolve the `impl Trait` to its concrete type.
163
- if let Some ( concrete_ty) = ty. subst ( tcx, substs) {
164
- let predicate = ty:: TraitRef {
165
- def_id : self . predicate . def_id ( ) ,
166
- substs : tcx. mk_substs_trait ( concrete_ty, & [ ] )
167
- } . to_predicate ( ) ;
168
-
169
- let original_obligation = Obligation :: new ( self . cause . clone ( ) ,
170
- self . predicate . clone ( ) ) ;
171
- let cause = original_obligation. derived_cause ( BuiltinDerivedObligation ) ;
172
- return Some ( vec ! [ Obligation :: new( cause, predicate) ] ) ;
173
- }
174
- }
175
-
176
- None
177
- }
178
-
179
- /// Return the `PredicateObligation` this was created from.
180
- pub fn to_obligation ( & self ) -> PredicateObligation < ' tcx > {
181
- let predicate = ty:: Predicate :: Trait ( self . predicate . clone ( ) ) ;
182
- Obligation :: new ( self . cause . clone ( ) , predicate)
183
- }
184
-
185
- /// Return an error as if this obligation had failed.
186
- pub fn to_error ( & self ) -> FulfillmentError < ' tcx > {
187
- FulfillmentError :: new ( self . to_obligation ( ) , CodeSelectionError ( Unimplemented ) )
188
- }
189
- }
190
-
191
97
impl < ' a , ' gcx , ' tcx > FulfillmentContext < ' tcx > {
192
98
/// Creates a new fulfillment context.
193
99
pub fn new ( ) -> FulfillmentContext < ' tcx > {
194
100
FulfillmentContext {
195
101
predicates : ObligationForest :: new ( ) ,
196
102
region_obligations : NodeMap ( ) ,
197
- deferred_obligations : vec ! [ ] ,
198
103
}
199
104
}
200
105
@@ -294,16 +199,10 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
294
199
{
295
200
self . select_where_possible ( infcx) ?;
296
201
297
- // Fail all of the deferred obligations that haven't
298
- // been otherwise removed from the context.
299
- let deferred_errors = self . deferred_obligations . iter ( )
300
- . map ( |d| d. to_error ( ) ) ;
301
-
302
202
let errors: Vec < _ > =
303
203
self . predicates . to_errors ( CodeAmbiguity )
304
204
. into_iter ( )
305
205
. map ( |e| to_fulfillment_error ( e) )
306
- . chain ( deferred_errors)
307
206
. collect ( ) ;
308
207
if errors. is_empty ( ) {
309
208
Ok ( ( ) )
@@ -324,10 +223,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
324
223
self . predicates . pending_obligations ( )
325
224
}
326
225
327
- pub fn take_deferred_obligations ( & mut self ) -> Vec < DeferredObligation < ' tcx > > {
328
- mem:: replace ( & mut self . deferred_obligations , vec ! [ ] )
329
- }
330
-
331
226
/// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
332
227
/// only attempts to select obligations that haven't been seen before.
333
228
fn select ( & mut self , selcx : & mut SelectionContext < ' a , ' gcx , ' tcx > )
@@ -343,7 +238,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
343
238
let outcome = self . predicates . process_obligations ( & mut FulfillProcessor {
344
239
selcx : selcx,
345
240
region_obligations : & mut self . region_obligations ,
346
- deferred_obligations : & mut self . deferred_obligations
347
241
} ) ;
348
242
debug ! ( "select: outcome={:?}" , outcome) ;
349
243
@@ -378,7 +272,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
378
272
struct FulfillProcessor < ' a , ' b : ' a , ' gcx : ' tcx , ' tcx : ' b > {
379
273
selcx : & ' a mut SelectionContext < ' b , ' gcx , ' tcx > ,
380
274
region_obligations : & ' a mut NodeMap < Vec < RegionObligation < ' tcx > > > ,
381
- deferred_obligations : & ' a mut Vec < DeferredObligation < ' tcx > >
382
275
}
383
276
384
277
impl < ' a , ' b , ' gcx , ' tcx > ObligationProcessor for FulfillProcessor < ' a , ' b , ' gcx , ' tcx > {
@@ -391,8 +284,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
391
284
{
392
285
process_predicate ( self . selcx ,
393
286
obligation,
394
- self . region_obligations ,
395
- self . deferred_obligations )
287
+ self . region_obligations )
396
288
. map ( |os| os. map ( |os| os. into_iter ( ) . map ( |o| PendingPredicateObligation {
397
289
obligation : o,
398
290
stalled_on : vec ! [ ]
@@ -432,8 +324,7 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
432
324
fn process_predicate < ' a , ' gcx , ' tcx > (
433
325
selcx : & mut SelectionContext < ' a , ' gcx , ' tcx > ,
434
326
pending_obligation : & mut PendingPredicateObligation < ' tcx > ,
435
- region_obligations : & mut NodeMap < Vec < RegionObligation < ' tcx > > > ,
436
- deferred_obligations : & mut Vec < DeferredObligation < ' tcx > > )
327
+ region_obligations : & mut NodeMap < Vec < RegionObligation < ' tcx > > > )
437
328
-> Result < Option < Vec < PredicateObligation < ' tcx > > > ,
438
329
FulfillmentErrorCode < ' tcx > >
439
330
{
@@ -502,21 +393,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
502
393
info ! ( "selecting trait `{:?}` at depth {} yielded Err" ,
503
394
data, obligation. recursion_depth) ;
504
395
505
- let defer = DeferredObligation :: from_select_error ( selcx. tcx ( ) ,
506
- & trait_obligation,
507
- & selection_err) ;
508
- if let Some ( deferred_obligation) = defer {
509
- if let Some ( nested) = deferred_obligation. try_select ( selcx. tcx ( ) ) {
510
- Ok ( Some ( nested) )
511
- } else {
512
- // Pretend that the obligation succeeded,
513
- // but record it for later.
514
- deferred_obligations. push ( deferred_obligation) ;
515
- Ok ( Some ( vec ! [ ] ) )
516
- }
517
- } else {
518
- Err ( CodeSelectionError ( selection_err) )
519
- }
396
+ Err ( CodeSelectionError ( selection_err) )
520
397
}
521
398
}
522
399
}
@@ -714,12 +591,6 @@ impl<'a, 'gcx, 'tcx> GlobalFulfilledPredicates<'gcx> {
714
591
// already has the required read edges, so we don't need
715
592
// to add any more edges here.
716
593
if data. is_global ( ) {
717
- // Don't cache predicates which were fulfilled
718
- // by deferring them for later fulfillment.
719
- if DeferredObligation :: must_defer ( tcx, data) {
720
- return ;
721
- }
722
-
723
594
if let Some ( data) = tcx. lift_to_global ( data) {
724
595
if self . set . insert ( data. clone ( ) ) {
725
596
debug ! ( "add_if_global: global predicate `{:?}` added" , data) ;
0 commit comments