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) ) ) ; 
@@ -318,7 +298,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
318298                               _marker :  PhantomData < & ' c  PendingPredicateObligation < ' tcx > > ) 
319299        where  I :  Clone  + Iterator < Item =& ' c  PendingPredicateObligation < ' tcx > > , 
320300    { 
321-         if  coinductive_match ( self . selcx ,   cycle. clone ( ) )  { 
301+         if  self . selcx . coinductive_match ( cycle. clone ( ) . map ( |s| s . obligation . predicate ) )  { 
322302            debug ! ( "process_child_obligations: coinductive match" ) ; 
323303        }  else  { 
324304            let  cycle :  Vec < _ >  = cycle. map ( |c| c. obligation . clone ( ) ) . collect ( ) ; 
@@ -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 
@@ -549,40 +539,6 @@ fn process_predicate<'a, 'gcx, 'tcx>(
549539    } 
550540} 
551541
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- } 
586542
587543fn  register_region_obligation < ' tcx > ( t_a :  Ty < ' tcx > , 
588544                                    r_b :  ty:: Region < ' tcx > , 
@@ -602,55 +558,6 @@ fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
602558
603559} 
604560
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- 
654561fn  to_fulfillment_error < ' tcx > ( 
655562    error :  Error < PendingPredicateObligation < ' tcx > ,  FulfillmentErrorCode < ' tcx > > ) 
656563    -> FulfillmentError < ' tcx > 
0 commit comments