@@ -5,22 +5,8 @@ use rustc_data_structures::{
55 graph:: { iterate:: DepthFirstSearch , vec_graph:: VecGraph } ,
66 stable_set:: FxHashSet ,
77} ;
8- use rustc_middle:: traits;
9- use rustc_middle:: ty:: { self , ToPredicate , Ty } ;
10- use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
11-
12- #[ derive( Default , Copy , Clone ) ]
13- struct FoundRelationships {
14- /// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
15- /// obligation, where:
16- ///
17- /// * `Foo` is not `Sized`
18- /// * `(): Foo` may be satisfied
19- self_in_trait : bool ,
20- /// This is true if we identified that this Ty (`?T`) is found in a `<_ as
21- /// _>::AssocType = ?T`
22- output : bool ,
23- }
8+ use rustc_middle:: ty:: { self , Ty } ;
9+
2410impl < ' tcx > FnCtxt < ' _ , ' tcx > {
2511 /// Performs type inference fallback, returning true if any fallback
2612 /// occurs.
@@ -30,60 +16,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
3016 self . fulfillment_cx. borrow_mut( ) . pending_obligations( )
3117 ) ;
3218
33- let mut relationships: FxHashMap < ty:: TyVid , FoundRelationships > = FxHashMap :: default ( ) ;
34- for obligation in self . fulfillment_cx . borrow_mut ( ) . pending_obligations ( ) {
35- if let ty:: PredicateKind :: Trait ( predicate, constness) =
36- obligation. predicate . kind ( ) . skip_binder ( )
37- {
38- if predicate. trait_ref . def_id
39- != self . infcx . tcx . require_lang_item ( rustc_hir:: LangItem :: Sized , None )
40- {
41- // fixme: copy of mk_trait_obligation_with_new_self_ty
42- let new_self_ty = self . infcx . tcx . types . unit ;
43-
44- let trait_ref = ty:: TraitRef {
45- substs : self
46- . infcx
47- . tcx
48- . mk_substs_trait ( new_self_ty, & predicate. trait_ref . substs [ 1 ..] ) ,
49- ..predicate. trait_ref
50- } ;
51-
52- // Then contstruct a new obligation with Self = () added
53- // to the ParamEnv, and see if it holds.
54- let o = rustc_infer:: traits:: Obligation :: new (
55- traits:: ObligationCause :: dummy ( ) ,
56- obligation. param_env ,
57- obligation
58- . predicate
59- . kind ( )
60- . map_bound ( |_| {
61- ty:: PredicateKind :: Trait (
62- ty:: TraitPredicate { trait_ref } ,
63- constness,
64- )
65- } )
66- . to_predicate ( self . infcx . tcx ) ,
67- ) ;
68- if self . infcx . predicate_may_hold ( & o) {
69- if let Some ( ty) = self . root_vid ( predicate. self_ty ( ) ) {
70- relationships. entry ( ty) . or_default ( ) . self_in_trait = true ;
71- }
72- }
73- }
74- }
75- if let ty:: PredicateKind :: Projection ( predicate) =
76- obligation. predicate . kind ( ) . skip_binder ( )
77- {
78- if let Some ( ty) = self . root_vid ( predicate. ty ) {
79- relationships. entry ( ty) . or_default ( ) . output = true ;
80- }
81- }
82- }
83-
8419 // All type checking constraints were added, try to fallback unsolved variables.
8520 self . select_obligations_where_possible ( false , |_| { } ) ;
8621
22+ let relationships = self . fulfillment_cx . borrow_mut ( ) . relationships ( ) . clone ( ) ;
23+
24+ debug ! ( "relationships: {:#?}" , relationships) ;
8725 debug ! (
8826 "type-inference-fallback post selection obligations: {:#?}" ,
8927 self . fulfillment_cx. borrow_mut( ) . pending_obligations( )
@@ -94,7 +32,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
9432 // Check if we have any unsolved varibales. If not, no need for fallback.
9533 let unsolved_variables = self . unsolved_variables ( ) ;
9634 if unsolved_variables. is_empty ( ) {
97- return ;
35+ return false ;
9836 }
9937
10038 let diverging_fallback =
@@ -324,7 +262,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
324262 fn calculate_diverging_fallback (
325263 & self ,
326264 unsolved_variables : & [ Ty < ' tcx > ] ,
327- relationships : & FxHashMap < ty:: TyVid , FoundRelationships > ,
265+ relationships : & FxHashMap < ty:: TyVid , ty :: FoundRelationships > ,
328266 ) -> FxHashMap < Ty < ' tcx > , Ty < ' tcx > > {
329267 debug ! ( "calculate_diverging_fallback({:?})" , unsolved_variables) ;
330268
@@ -413,6 +351,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
413351
414352 debug ! ( "inherited: {:#?}" , self . inh. fulfillment_cx. borrow_mut( ) . pending_obligations( ) ) ;
415353 debug ! ( "obligations: {:#?}" , self . fulfillment_cx. borrow_mut( ) . pending_obligations( ) ) ;
354+ debug ! ( "relationships: {:#?}" , relationships) ;
416355
417356 // For each diverging variable, figure out whether it can
418357 // reach a member of N. If so, it falls back to `()`. Else
@@ -426,7 +365,15 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
426365 . depth_first_search ( root_vid)
427366 . any ( |n| roots_reachable_from_non_diverging. visited ( n) ) ;
428367
429- let relationship = relationships. get ( & root_vid) . copied ( ) . unwrap_or_default ( ) ;
368+ let mut relationship = ty:: FoundRelationships { self_in_trait : false , output : false } ;
369+
370+ for ( vid, rel) in relationships. iter ( ) {
371+ //if self.infcx.shallow_resolve(*ty).ty_vid().map(|t| self.infcx.root_var(t))
372+ if self . infcx . root_var ( * vid) == root_vid {
373+ relationship. self_in_trait |= rel. self_in_trait ;
374+ relationship. output |= rel. output ;
375+ }
376+ }
430377
431378 if relationship. self_in_trait && relationship. output {
432379 debug ! ( "fallback to () - found trait and projection: {:?}" , diverging_vid) ;
0 commit comments