88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use dep_graph:: DepGraph ;
1211use infer:: { InferCtxt , InferOk } ;
13- use ty:: { self , Ty , TypeFoldable , ToPolyTraitRef , TyCtxt , ToPredicate } ;
12+ use ty:: { self , Ty , TypeFoldable , ToPolyTraitRef , ToPredicate } ;
1413use ty:: error:: ExpectedFound ;
1514use rustc_data_structures:: obligation_forest:: { ObligationForest , Error } ;
1615use rustc_data_structures:: obligation_forest:: { ForestObligation , ObligationProcessor } ;
1716use std:: marker:: PhantomData ;
1817use syntax:: ast;
19- use util:: nodemap:: { FxHashSet , NodeMap } ;
18+ use util:: nodemap:: NodeMap ;
2019use hir:: def_id:: DefId ;
2120
2221use super :: CodeAmbiguity ;
@@ -34,11 +33,6 @@ impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
3433 fn as_predicate ( & self ) -> & Self :: Predicate { & self . obligation . predicate }
3534}
3635
37- pub struct GlobalFulfilledPredicates < ' tcx > {
38- set : FxHashSet < ty:: PolyTraitPredicate < ' tcx > > ,
39- dep_graph : DepGraph ,
40- }
41-
4236/// The fulfillment context is used to drive trait resolution. It
4337/// consists of a list of obligations that must be (eventually)
4438/// satisfied. The job is to track which are satisfied, which yielded
@@ -183,13 +177,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
183177
184178 assert ! ( !infcx. is_in_snapshot( ) ) ;
185179
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-
193180 self . predicates . register_obligation ( PendingPredicateObligation {
194181 obligation,
195182 stalled_on : vec ! [ ]
@@ -264,13 +251,6 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
264251 } ) ;
265252 debug ! ( "select: outcome={:?}" , outcome) ;
266253
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-
274254 errors. extend (
275255 outcome. errors . into_iter ( )
276256 . map ( |e| to_fulfillment_error ( e) ) ) ;
@@ -375,21 +355,31 @@ fn process_predicate<'a, 'gcx, 'tcx>(
375355
376356 match obligation. predicate {
377357 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+ }
381372 }
382373
383- let trait_obligation = obligation. with ( data. clone ( ) ) ;
384374 match selcx. select ( & trait_obligation) {
385375 Ok ( Some ( vtable) ) => {
386376 debug ! ( "selecting trait `{:?}` at depth {} yielded Ok(Some)" ,
387- data, obligation. recursion_depth) ;
377+ data, obligation. recursion_depth) ;
388378 Ok ( Some ( vtable. nested_obligations ( ) ) )
389379 }
390380 Ok ( None ) => {
391381 debug ! ( "selecting trait `{:?}` at depth {} yielded Ok(None)" ,
392- data, obligation. recursion_depth) ;
382+ data, obligation. recursion_depth) ;
393383
394384 // This is a bit subtle: for the most part, the
395385 // only reason we can fail to make progress on
@@ -568,55 +558,6 @@ fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
568558
569559}
570560
571- impl < ' a , ' gcx , ' tcx > GlobalFulfilledPredicates < ' gcx > {
572- pub fn new ( dep_graph : DepGraph ) -> GlobalFulfilledPredicates < ' gcx > {
573- GlobalFulfilledPredicates {
574- set : FxHashSet ( ) ,
575- dep_graph,
576- }
577- }
578-
579- pub fn check_duplicate ( & self , tcx : TyCtxt , key : & ty:: Predicate < ' tcx > ) -> bool {
580- if let ty:: Predicate :: Trait ( ref data) = * key {
581- self . check_duplicate_trait ( tcx, data)
582- } else {
583- false
584- }
585- }
586-
587- pub fn check_duplicate_trait ( & self , tcx : TyCtxt , data : & ty:: PolyTraitPredicate < ' tcx > ) -> bool {
588- // For the global predicate registry, when we find a match, it
589- // may have been computed by some other task, so we want to
590- // add a read from the node corresponding to the predicate
591- // processing to make sure we get the transitive dependencies.
592- if self . set . contains ( data) {
593- debug_assert ! ( data. is_global( ) ) ;
594- self . dep_graph . read ( data. dep_node ( tcx) ) ;
595- debug ! ( "check_duplicate: global predicate `{:?}` already proved elsewhere" , data) ;
596-
597- true
598- } else {
599- false
600- }
601- }
602-
603- fn add_if_global ( & mut self , tcx : TyCtxt < ' a , ' gcx , ' tcx > , key : & ty:: Predicate < ' tcx > ) {
604- if let ty:: Predicate :: Trait ( ref data) = * key {
605- // We only add things to the global predicate registry
606- // after the current task has proved them, and hence
607- // already has the required read edges, so we don't need
608- // to add any more edges here.
609- if data. is_global ( ) {
610- if let Some ( data) = tcx. lift_to_global ( data) {
611- if self . set . insert ( data. clone ( ) ) {
612- debug ! ( "add_if_global: global predicate `{:?}` added" , data) ;
613- }
614- }
615- }
616- }
617- }
618- }
619-
620561fn to_fulfillment_error < ' tcx > (
621562 error : Error < PendingPredicateObligation < ' tcx > , FulfillmentErrorCode < ' tcx > > )
622563 -> FulfillmentError < ' tcx >
0 commit comments