@@ -28,8 +28,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2828use rustc_hir:: intravisit:: { walk_generics, Visitor as _} ;
2929use rustc_hir:: { GenericArg , GenericArgs , OpaqueTyOrigin } ;
3030use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
31- use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
32- use rustc_infer:: traits:: ObligationCause ;
31+ use rustc_infer:: infer:: { InferCtxt , InferOk , TyCtxtInferExt } ;
32+ use rustc_infer:: traits:: { ObligationCause , PredicateObligations } ;
3333use rustc_middle:: infer:: unify_key:: { ConstVariableOrigin , ConstVariableOriginKind } ;
3434use rustc_middle:: middle:: stability:: AllowUnstable ;
3535use rustc_middle:: ty:: subst:: { self , GenericArgKind , InternalSubsts , SubstsRef } ;
@@ -46,7 +46,9 @@ use rustc_trait_selection::traits::error_reporting::{
4646 report_object_safety_error, suggestions:: NextTypeParamName ,
4747} ;
4848use rustc_trait_selection:: traits:: wf:: object_region_bounds;
49- use rustc_trait_selection:: traits:: { self , astconv_object_safety_violations, ObligationCtxt } ;
49+ use rustc_trait_selection:: traits:: {
50+ self , astconv_object_safety_violations, NormalizeExt , ObligationCtxt ,
51+ } ;
5052
5153use smallvec:: { smallvec, SmallVec } ;
5254use std:: collections:: BTreeSet ;
@@ -127,6 +129,8 @@ pub trait AstConv<'tcx> {
127129
128130 fn record_ty ( & self , hir_id : hir:: HirId , ty : Ty < ' tcx > , span : Span ) ;
129131
132+ fn register_predicate_obligations ( & self , obligations : PredicateObligations < ' tcx > ) ;
133+
130134 fn astconv ( & self ) -> & dyn AstConv < ' tcx >
131135 where
132136 Self : Sized ,
@@ -2234,7 +2238,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22342238 let mut fulfillment_errors = Vec :: new ( ) ;
22352239 let mut applicable_candidates: Vec < _ > = candidates
22362240 . iter ( )
2237- . filter_map ( |& ( impl_, ( assoc_item , def_scope ) ) | {
2241+ . filter_map ( |& ( impl_, item ) | {
22382242 infcx. probe ( |_| {
22392243 let ocx = ObligationCtxt :: new_in_snapshot ( & infcx) ;
22402244
@@ -2250,15 +2254,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22502254 // Check whether the impl imposes obligations we have to worry about.
22512255 let impl_bounds = tcx. predicates_of ( impl_) ;
22522256 let impl_bounds = impl_bounds. instantiate ( tcx, impl_substs) ;
2253-
22542257 let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
2255-
22562258 let impl_obligations = traits:: predicates_for_generics (
22572259 |_, _| cause. clone ( ) ,
22582260 param_env,
22592261 impl_bounds,
22602262 ) ;
2261-
22622263 ocx. register_obligations ( impl_obligations) ;
22632264
22642265 let mut errors = ocx. select_where_possible ( ) ;
@@ -2267,26 +2268,66 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22672268 return None ;
22682269 }
22692270
2270- // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2271- Some ( ( assoc_item, def_scope, infcx. resolve_vars_if_possible ( impl_substs) ) )
2271+ let impl_substs = if !self . allow_ty_infer ( ) {
2272+ let substs = infcx. resolve_vars_if_possible ( impl_substs) ;
2273+ assert ! ( !substs. needs_infer( ) ) ;
2274+ Some ( substs)
2275+ } else {
2276+ None
2277+ } ;
2278+
2279+ Some ( ( item, impl_, impl_substs) )
22722280 } )
22732281 } )
22742282 . collect ( ) ;
22752283
22762284 if applicable_candidates. len ( ) > 1 {
22772285 return Err ( self . complain_about_ambiguous_inherent_assoc_type (
22782286 name,
2279- applicable_candidates. into_iter ( ) . map ( |( candidate, ..) | candidate) . collect ( ) ,
2287+ applicable_candidates. into_iter ( ) . map ( |( ( candidate, .. ) , ..) | candidate) . collect ( ) ,
22802288 span,
22812289 ) ) ;
22822290 }
22832291
2284- if let Some ( ( assoc_item, def_scope, impl_substs) ) = applicable_candidates. pop ( ) {
2292+ if let Some ( ( ( assoc_item, def_scope) , impl_, probe_impl_substs) ) =
2293+ applicable_candidates. pop ( )
2294+ {
22852295 self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
22862296
2287- // FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate, we still
2288- // need to relate the Self-type with fresh item substs & register region obligations for
2289- // regionck to prove/disprove.
2297+ // FIXME(fmease, inherent_associated_types): Register WF obligations for the Self type.
2298+ // At the moment, we don't regionck the Self type or the substitutions.
2299+
2300+ let impl_substs;
2301+ if let Some ( probe_impl_substs) = probe_impl_substs {
2302+ impl_substs = probe_impl_substs;
2303+ } else {
2304+ impl_substs = infcx. fresh_item_substs ( impl_) ;
2305+
2306+ let impl_bounds = tcx. predicates_of ( impl_) ;
2307+ let impl_bounds = impl_bounds. instantiate ( tcx, impl_substs) ;
2308+ let InferOk { value : impl_bounds, obligations : norm_obligations } =
2309+ infcx. at ( & cause, param_env) . normalize ( impl_bounds) ;
2310+ self . register_predicate_obligations ( norm_obligations) ;
2311+ let impl_obligations =
2312+ traits:: predicates_for_generics ( |_, _| cause. clone ( ) , param_env, impl_bounds) ;
2313+ self . register_predicate_obligations ( impl_obligations. collect ( ) ) ;
2314+
2315+ let impl_ty = tcx. type_of ( impl_) ;
2316+ let impl_ty = impl_ty. subst ( tcx, impl_substs) ;
2317+ let InferOk { value : impl_ty, obligations : norm_obligations } =
2318+ infcx. at ( & cause, param_env) . normalize ( impl_ty) ;
2319+ self . register_predicate_obligations ( norm_obligations) ;
2320+
2321+ match infcx. at ( & cause, param_env) . eq ( impl_ty, self_ty) {
2322+ Ok ( ok) => self . register_predicate_obligations ( ok. obligations ) ,
2323+ Err ( _) => {
2324+ tcx. sess . delay_span_bug (
2325+ span,
2326+ & format ! ( "{self_ty:?} was a subtype of {impl_ty:?} but now it is not?" ) ,
2327+ ) ;
2328+ }
2329+ }
2330+ }
22902331
22912332 let item_substs =
22922333 self . create_substs_for_associated_item ( span, assoc_item, segment, impl_substs) ;
0 commit comments