@@ -28,8 +28,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
28
28
use rustc_hir:: intravisit:: { walk_generics, Visitor as _} ;
29
29
use rustc_hir:: { GenericArg , GenericArgs , OpaqueTyOrigin } ;
30
30
use 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 } ;
33
33
use rustc_middle:: infer:: unify_key:: { ConstVariableOrigin , ConstVariableOriginKind } ;
34
34
use rustc_middle:: middle:: stability:: AllowUnstable ;
35
35
use rustc_middle:: ty:: subst:: { self , GenericArgKind , InternalSubsts , SubstsRef } ;
@@ -46,7 +46,9 @@ use rustc_trait_selection::traits::error_reporting::{
46
46
report_object_safety_error, suggestions:: NextTypeParamName ,
47
47
} ;
48
48
use 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
+ } ;
50
52
51
53
use smallvec:: { smallvec, SmallVec } ;
52
54
use std:: collections:: BTreeSet ;
@@ -127,6 +129,8 @@ pub trait AstConv<'tcx> {
127
129
128
130
fn record_ty ( & self , hir_id : hir:: HirId , ty : Ty < ' tcx > , span : Span ) ;
129
131
132
+ fn register_predicate_obligations ( & self , obligations : PredicateObligations < ' tcx > ) ;
133
+
130
134
fn astconv ( & self ) -> & dyn AstConv < ' tcx >
131
135
where
132
136
Self : Sized ,
@@ -2234,7 +2238,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2234
2238
let mut fulfillment_errors = Vec :: new ( ) ;
2235
2239
let mut applicable_candidates: Vec < _ > = candidates
2236
2240
. iter ( )
2237
- . filter_map ( |& ( impl_, ( assoc_item , def_scope ) ) | {
2241
+ . filter_map ( |& ( impl_, item ) | {
2238
2242
infcx. probe ( |_| {
2239
2243
let ocx = ObligationCtxt :: new_in_snapshot ( & infcx) ;
2240
2244
@@ -2250,15 +2254,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2250
2254
// Check whether the impl imposes obligations we have to worry about.
2251
2255
let impl_bounds = tcx. predicates_of ( impl_) ;
2252
2256
let impl_bounds = impl_bounds. instantiate ( tcx, impl_substs) ;
2253
-
2254
2257
let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
2255
-
2256
2258
let impl_obligations = traits:: predicates_for_generics (
2257
2259
|_, _| cause. clone ( ) ,
2258
2260
param_env,
2259
2261
impl_bounds,
2260
2262
) ;
2261
-
2262
2263
ocx. register_obligations ( impl_obligations) ;
2263
2264
2264
2265
let mut errors = ocx. select_where_possible ( ) ;
@@ -2267,26 +2268,66 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2267
2268
return None ;
2268
2269
}
2269
2270
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) )
2272
2280
} )
2273
2281
} )
2274
2282
. collect ( ) ;
2275
2283
2276
2284
if applicable_candidates. len ( ) > 1 {
2277
2285
return Err ( self . complain_about_ambiguous_inherent_assoc_type (
2278
2286
name,
2279
- applicable_candidates. into_iter ( ) . map ( |( candidate, ..) | candidate) . collect ( ) ,
2287
+ applicable_candidates. into_iter ( ) . map ( |( ( candidate, .. ) , ..) | candidate) . collect ( ) ,
2280
2288
span,
2281
2289
) ) ;
2282
2290
}
2283
2291
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
+ {
2285
2295
self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
2286
2296
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
+ }
2290
2331
2291
2332
let item_substs =
2292
2333
self . create_substs_for_associated_item ( span, assoc_item, segment, impl_substs) ;
0 commit comments