@@ -5,22 +5,8 @@ use rustc_data_structures::{
5
5
graph:: { iterate:: DepthFirstSearch , vec_graph:: VecGraph } ,
6
6
stable_set:: FxHashSet ,
7
7
} ;
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
+
24
10
impl < ' tcx > FnCtxt < ' _ , ' tcx > {
25
11
/// Performs type inference fallback, returning true if any fallback
26
12
/// occurs.
@@ -30,60 +16,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
30
16
self . fulfillment_cx. borrow_mut( ) . pending_obligations( )
31
17
) ;
32
18
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
-
84
19
// All type checking constraints were added, try to fallback unsolved variables.
85
20
self . select_obligations_where_possible ( false , |_| { } ) ;
86
21
22
+ let relationships = self . fulfillment_cx . borrow_mut ( ) . relationships ( ) . clone ( ) ;
23
+
24
+ debug ! ( "relationships: {:#?}" , relationships) ;
87
25
debug ! (
88
26
"type-inference-fallback post selection obligations: {:#?}" ,
89
27
self . fulfillment_cx. borrow_mut( ) . pending_obligations( )
@@ -94,7 +32,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
94
32
// Check if we have any unsolved varibales. If not, no need for fallback.
95
33
let unsolved_variables = self . unsolved_variables ( ) ;
96
34
if unsolved_variables. is_empty ( ) {
97
- return ;
35
+ return false ;
98
36
}
99
37
100
38
let diverging_fallback =
@@ -324,7 +262,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
324
262
fn calculate_diverging_fallback (
325
263
& self ,
326
264
unsolved_variables : & [ Ty < ' tcx > ] ,
327
- relationships : & FxHashMap < ty:: TyVid , FoundRelationships > ,
265
+ relationships : & FxHashMap < ty:: TyVid , ty :: FoundRelationships > ,
328
266
) -> FxHashMap < Ty < ' tcx > , Ty < ' tcx > > {
329
267
debug ! ( "calculate_diverging_fallback({:?})" , unsolved_variables) ;
330
268
@@ -413,6 +351,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
413
351
414
352
debug ! ( "inherited: {:#?}" , self . inh. fulfillment_cx. borrow_mut( ) . pending_obligations( ) ) ;
415
353
debug ! ( "obligations: {:#?}" , self . fulfillment_cx. borrow_mut( ) . pending_obligations( ) ) ;
354
+ debug ! ( "relationships: {:#?}" , relationships) ;
416
355
417
356
// For each diverging variable, figure out whether it can
418
357
// reach a member of N. If so, it falls back to `()`. Else
@@ -426,7 +365,15 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
426
365
. depth_first_search ( root_vid)
427
366
. any ( |n| roots_reachable_from_non_diverging. visited ( n) ) ;
428
367
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
+ }
430
377
431
378
if relationship. self_in_trait && relationship. output {
432
379
debug ! ( "fallback to () - found trait and projection: {:?}" , diverging_vid) ;
0 commit comments