8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use dep_graph:: DepGraph ;
12
11
use infer:: { InferCtxt , InferOk } ;
13
- use ty:: { self , Ty , TypeFoldable , ToPolyTraitRef , TyCtxt , ToPredicate } ;
12
+ use ty:: { self , Ty , TypeFoldable , ToPolyTraitRef , ToPredicate } ;
14
13
use ty:: error:: ExpectedFound ;
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
17
use syntax:: ast;
19
- use util:: nodemap:: { FxHashSet , NodeMap } ;
18
+ use util:: nodemap:: NodeMap ;
20
19
use hir:: def_id:: DefId ;
21
20
22
21
use super :: CodeAmbiguity ;
@@ -34,11 +33,6 @@ impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
34
33
fn as_predicate ( & self ) -> & Self :: Predicate { & self . obligation . predicate }
35
34
}
36
35
37
- pub struct GlobalFulfilledPredicates < ' tcx > {
38
- set : FxHashSet < ty:: PolyTraitPredicate < ' tcx > > ,
39
- dep_graph : DepGraph ,
40
- }
41
-
42
36
/// The fulfillment context is used to drive trait resolution. It
43
37
/// consists of a list of obligations that must be (eventually)
44
38
/// satisfied. The job is to track which are satisfied, which yielded
@@ -183,13 +177,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
183
177
184
178
assert ! ( !infcx. is_in_snapshot( ) ) ;
185
179
186
- let tcx = infcx. tcx ;
187
-
188
- if tcx. fulfilled_predicates . borrow ( ) . check_duplicate ( tcx, & obligation. predicate ) {
189
- debug ! ( "register_predicate_obligation: duplicate" ) ;
190
- return
191
- }
192
-
193
180
self . predicates . register_obligation ( PendingPredicateObligation {
194
181
obligation,
195
182
stalled_on : vec ! [ ]
@@ -264,13 +251,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
264
251
} ) ;
265
252
debug ! ( "select: outcome={:?}" , outcome) ;
266
253
267
- // these are obligations that were proven to be true.
268
- for pending_obligation in outcome. completed {
269
- let predicate = & pending_obligation. obligation . predicate ;
270
- selcx. tcx ( ) . fulfilled_predicates . borrow_mut ( )
271
- . add_if_global ( selcx. tcx ( ) , predicate) ;
272
- }
273
-
274
254
errors. extend (
275
255
outcome. errors . into_iter ( )
276
256
. map ( |e| to_fulfillment_error ( e) ) ) ;
@@ -318,7 +298,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
318
298
_marker : PhantomData < & ' c PendingPredicateObligation < ' tcx > > )
319
299
where I : Clone + Iterator < Item =& ' c PendingPredicateObligation < ' tcx > > ,
320
300
{
321
- if coinductive_match ( self . selcx , cycle. clone ( ) ) {
301
+ if self . selcx . coinductive_match ( cycle. clone ( ) . map ( |s| s . obligation . predicate ) ) {
322
302
debug ! ( "process_child_obligations: coinductive match" ) ;
323
303
} else {
324
304
let cycle : Vec < _ > = cycle. map ( |c| c. obligation . clone ( ) ) . collect ( ) ;
@@ -375,21 +355,31 @@ fn process_predicate<'a, 'gcx, 'tcx>(
375
355
376
356
match obligation. predicate {
377
357
ty:: Predicate :: Trait ( ref data) => {
378
- let tcx = selcx. tcx ( ) ;
379
- if tcx. fulfilled_predicates . borrow ( ) . check_duplicate_trait ( tcx, data) {
380
- return Ok ( Some ( vec ! [ ] ) ) ;
358
+ let trait_obligation = obligation. with ( data. clone ( ) ) ;
359
+
360
+ if data. is_global ( ) {
361
+ // no type variables present, can use evaluation for better caching.
362
+ // FIXME: consider caching errors too.
363
+ if
364
+ // make defaulted unit go through the slow path for better warnings,
365
+ // please remove this when the warnings are removed.
366
+ !trait_obligation. predicate . skip_binder ( ) . self_ty ( ) . is_defaulted_unit ( ) &&
367
+ selcx. evaluate_obligation_conservatively ( & obligation) {
368
+ debug ! ( "selecting trait `{:?}` at depth {} evaluated to holds" ,
369
+ data, obligation. recursion_depth) ;
370
+ return Ok ( Some ( vec ! [ ] ) )
371
+ }
381
372
}
382
373
383
- let trait_obligation = obligation. with ( data. clone ( ) ) ;
384
374
match selcx. select ( & trait_obligation) {
385
375
Ok ( Some ( vtable) ) => {
386
376
debug ! ( "selecting trait `{:?}` at depth {} yielded Ok(Some)" ,
387
- data, obligation. recursion_depth) ;
377
+ data, obligation. recursion_depth) ;
388
378
Ok ( Some ( vtable. nested_obligations ( ) ) )
389
379
}
390
380
Ok ( None ) => {
391
381
debug ! ( "selecting trait `{:?}` at depth {} yielded Ok(None)" ,
392
- data, obligation. recursion_depth) ;
382
+ data, obligation. recursion_depth) ;
393
383
394
384
// This is a bit subtle: for the most part, the
395
385
// only reason we can fail to make progress on
@@ -549,40 +539,6 @@ fn process_predicate<'a, 'gcx, 'tcx>(
549
539
}
550
540
}
551
541
552
- /// For defaulted traits, we use a co-inductive strategy to solve, so
553
- /// that recursion is ok. This routine returns true if the top of the
554
- /// stack (`cycle[0]`):
555
- /// - is a defaulted trait, and
556
- /// - it also appears in the backtrace at some position `X`; and,
557
- /// - all the predicates at positions `X..` between `X` an the top are
558
- /// also defaulted traits.
559
- fn coinductive_match < ' a , ' c , ' gcx , ' tcx , I > ( selcx : & mut SelectionContext < ' a , ' gcx , ' tcx > ,
560
- cycle : I ) -> bool
561
- where I : Iterator < Item =& ' c PendingPredicateObligation < ' tcx > > ,
562
- ' tcx : ' c
563
- {
564
- let mut cycle = cycle;
565
- cycle
566
- . all ( |bt_obligation| {
567
- let result = coinductive_obligation ( selcx, & bt_obligation. obligation ) ;
568
- debug ! ( "coinductive_match: bt_obligation={:?} coinductive={}" ,
569
- bt_obligation, result) ;
570
- result
571
- } )
572
- }
573
-
574
- fn coinductive_obligation < ' a , ' gcx , ' tcx > ( selcx : & SelectionContext < ' a , ' gcx , ' tcx > ,
575
- obligation : & PredicateObligation < ' tcx > )
576
- -> bool {
577
- match obligation. predicate {
578
- ty:: Predicate :: Trait ( ref data) => {
579
- selcx. tcx ( ) . trait_has_default_impl ( data. def_id ( ) )
580
- }
581
- _ => {
582
- false
583
- }
584
- }
585
- }
586
542
587
543
fn register_region_obligation < ' tcx > ( t_a : Ty < ' tcx > ,
588
544
r_b : ty:: Region < ' tcx > ,
@@ -602,55 +558,6 @@ fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
602
558
603
559
}
604
560
605
- impl < ' a , ' gcx , ' tcx > GlobalFulfilledPredicates < ' gcx > {
606
- pub fn new ( dep_graph : DepGraph ) -> GlobalFulfilledPredicates < ' gcx > {
607
- GlobalFulfilledPredicates {
608
- set : FxHashSet ( ) ,
609
- dep_graph,
610
- }
611
- }
612
-
613
- pub fn check_duplicate ( & self , tcx : TyCtxt , key : & ty:: Predicate < ' tcx > ) -> bool {
614
- if let ty:: Predicate :: Trait ( ref data) = * key {
615
- self . check_duplicate_trait ( tcx, data)
616
- } else {
617
- false
618
- }
619
- }
620
-
621
- pub fn check_duplicate_trait ( & self , tcx : TyCtxt , data : & ty:: PolyTraitPredicate < ' tcx > ) -> bool {
622
- // For the global predicate registry, when we find a match, it
623
- // may have been computed by some other task, so we want to
624
- // add a read from the node corresponding to the predicate
625
- // processing to make sure we get the transitive dependencies.
626
- if self . set . contains ( data) {
627
- debug_assert ! ( data. is_global( ) ) ;
628
- self . dep_graph . read ( data. dep_node ( tcx) ) ;
629
- debug ! ( "check_duplicate: global predicate `{:?}` already proved elsewhere" , data) ;
630
-
631
- true
632
- } else {
633
- false
634
- }
635
- }
636
-
637
- fn add_if_global ( & mut self , tcx : TyCtxt < ' a , ' gcx , ' tcx > , key : & ty:: Predicate < ' tcx > ) {
638
- if let ty:: Predicate :: Trait ( ref data) = * key {
639
- // We only add things to the global predicate registry
640
- // after the current task has proved them, and hence
641
- // already has the required read edges, so we don't need
642
- // to add any more edges here.
643
- if data. is_global ( ) {
644
- if let Some ( data) = tcx. lift_to_global ( data) {
645
- if self . set . insert ( data. clone ( ) ) {
646
- debug ! ( "add_if_global: global predicate `{:?}` added" , data) ;
647
- }
648
- }
649
- }
650
- }
651
- }
652
- }
653
-
654
561
fn to_fulfillment_error < ' tcx > (
655
562
error : Error < PendingPredicateObligation < ' tcx > , FulfillmentErrorCode < ' tcx > > )
656
563
-> FulfillmentError < ' tcx >
0 commit comments