@@ -10,7 +10,8 @@ use rustc_middle::ty::visit::TypeVisitable;
10
10
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
11
11
use rustc_span:: def_id:: LocalDefIdMap ;
12
12
use rustc_span:: { self , Span } ;
13
- use rustc_trait_selection:: traits:: { self , TraitEngine , TraitEngineExt as _} ;
13
+ use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
14
+ use rustc_trait_selection:: traits:: { self , PredicateObligation , TraitEngine , TraitEngineExt as _} ;
14
15
15
16
use std:: cell:: RefCell ;
16
17
use std:: ops:: Deref ;
@@ -140,11 +141,7 @@ impl<'tcx> Inherited<'tcx> {
140
141
span_bug ! ( obligation. cause. span, "escaping bound vars in predicate {:?}" , obligation) ;
141
142
}
142
143
143
- super :: relationships:: update (
144
- & self . infcx ,
145
- & mut self . relationships . borrow_mut ( ) ,
146
- & obligation,
147
- ) ;
144
+ self . update_infer_var_info ( & obligation) ;
148
145
149
146
self . fulfillment_cx . borrow_mut ( ) . register_predicate_obligation ( self , obligation) ;
150
147
}
@@ -162,4 +159,43 @@ impl<'tcx> Inherited<'tcx> {
162
159
self . register_predicates ( infer_ok. obligations ) ;
163
160
infer_ok. value
164
161
}
162
+
163
+ pub fn update_infer_var_info ( & self , obligation : & PredicateObligation < ' tcx > ) {
164
+ let relationships = & mut self . relationships . borrow_mut ( ) ;
165
+
166
+ // (*) binder skipped
167
+ if let ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( tpred) ) = obligation. predicate . kind ( ) . skip_binder ( )
168
+ && let Some ( ty) = self . shallow_resolve ( tpred. self_ty ( ) ) . ty_vid ( ) . map ( |t| self . root_var ( t) )
169
+ && self . tcx . lang_items ( ) . sized_trait ( ) . map_or ( false , |st| st != tpred. trait_ref . def_id )
170
+ {
171
+ let new_self_ty = self . tcx . types . unit ;
172
+
173
+ // Then construct a new obligation with Self = () added
174
+ // to the ParamEnv, and see if it holds.
175
+ let o = obligation. with ( self . tcx ,
176
+ obligation
177
+ . predicate
178
+ . kind ( )
179
+ . rebind (
180
+ // (*) binder moved here
181
+ ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( tpred. with_self_ty ( self . tcx , new_self_ty) ) )
182
+ ) ,
183
+ ) ;
184
+ // Don't report overflow errors. Otherwise equivalent to may_hold.
185
+ if let Ok ( result) = self . probe ( |_| self . evaluate_obligation ( & o) ) && result. may_apply ( ) {
186
+ relationships. entry ( ty) . or_default ( ) . self_in_trait = true ;
187
+ }
188
+ }
189
+
190
+ if let ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( predicate) ) =
191
+ obligation. predicate . kind ( ) . skip_binder ( )
192
+ {
193
+ // If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
194
+ // we need to make it into one.
195
+ if let Some ( vid) = predicate. term . ty ( ) . and_then ( |ty| ty. ty_vid ( ) ) {
196
+ debug ! ( "relationships: {:?}.output = true" , vid) ;
197
+ relationships. entry ( vid) . or_default ( ) . output = true ;
198
+ }
199
+ }
200
+ }
165
201
}
0 commit comments