@@ -10,7 +10,8 @@ use rustc_middle::ty::visit::TypeVisitable;
1010use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1111use rustc_span:: def_id:: LocalDefIdMap ;
1212use 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 _} ;
1415
1516use std:: cell:: RefCell ;
1617use std:: ops:: Deref ;
@@ -140,11 +141,7 @@ impl<'tcx> Inherited<'tcx> {
140141 span_bug ! ( obligation. cause. span, "escaping bound vars in predicate {:?}" , obligation) ;
141142 }
142143
143- super :: relationships:: update (
144- & self . infcx ,
145- & mut self . relationships . borrow_mut ( ) ,
146- & obligation,
147- ) ;
144+ self . update_infer_var_info ( & obligation) ;
148145
149146 self . fulfillment_cx . borrow_mut ( ) . register_predicate_obligation ( self , obligation) ;
150147 }
@@ -162,4 +159,43 @@ impl<'tcx> Inherited<'tcx> {
162159 self . register_predicates ( infer_ok. obligations ) ;
163160 infer_ok. value
164161 }
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+ }
165201}
0 commit comments