@@ -26,10 +26,9 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
2626use rustc_hir:: def_id:: { DefId , LocalDefId } ;
2727use rustc_hir:: intravisit:: { walk_generics, Visitor as _} ;
2828use rustc_hir:: { GenericArg , GenericArgs , OpaqueTyOrigin } ;
29- use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
29+ use rustc_infer:: infer:: { InferCtxt , InferOk , TyCtxtInferExt } ;
3030use rustc_infer:: traits:: ObligationCause ;
3131use rustc_middle:: middle:: stability:: AllowUnstable ;
32- use rustc_middle:: ty:: fold:: FnMutDelegate ;
3332use rustc_middle:: ty:: subst:: { self , GenericArgKind , InternalSubsts , SubstsRef } ;
3433use rustc_middle:: ty:: GenericParamDefKind ;
3534use rustc_middle:: ty:: { self , Const , IsSuggestable , Ty , TyCtxt , TypeVisitableExt } ;
@@ -43,7 +42,10 @@ use rustc_trait_selection::traits::error_reporting::{
4342 report_object_safety_error, suggestions:: NextTypeParamName ,
4443} ;
4544use rustc_trait_selection:: traits:: wf:: object_region_bounds;
46- use rustc_trait_selection:: traits:: { self , astconv_object_safety_violations, ObligationCtxt } ;
45+ use rustc_trait_selection:: traits:: {
46+ self , astconv_object_safety_violations, NormalizeExt , ObligationCtxt ,
47+ } ;
48+ use rustc_type_ir:: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable } ;
4749
4850use smallvec:: { smallvec, SmallVec } ;
4951use std:: collections:: BTreeSet ;
@@ -2442,6 +2444,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24422444 return Ok ( None ) ;
24432445 }
24442446
2447+ if !tcx. features ( ) . inherent_associated_types {
2448+ tcx. sess
2449+ . delay_span_bug ( span, "found inherent assoc type without the feature being gated" ) ;
2450+ }
2451+
24452452 //
24462453 // Select applicable inherent associated type candidates modulo regions.
24472454 //
@@ -2465,30 +2472,61 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24652472
24662473 let mut fulfillment_errors = Vec :: new ( ) ;
24672474 let mut applicable_candidates: Vec < _ > = infcx. probe ( |_| {
2468- let universe = infcx. create_next_universe ( ) ;
2469-
24702475 // Regions are not considered during selection.
2471- // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes
2472- // of type and const binders. Is that correct in the selection phase? See also #109505.
2473- let self_ty = tcx. replace_escaping_bound_vars_uncached (
2474- self_ty,
2475- FnMutDelegate {
2476- regions : & mut |_| tcx. lifetimes . re_erased ,
2477- types : & mut |bv| {
2478- tcx. mk_placeholder ( ty:: PlaceholderType { universe, bound : bv } )
2479- } ,
2480- consts : & mut |bv, ty| {
2481- tcx. mk_const ( ty:: PlaceholderConst { universe, bound : bv } , ty)
2482- } ,
2483- } ,
2484- ) ;
2476+ let self_ty = self_ty
2477+ . fold_with ( & mut BoundVarEraser { tcx, universe : infcx. create_next_universe ( ) } ) ;
2478+
2479+ struct BoundVarEraser < ' tcx > {
2480+ tcx : TyCtxt < ' tcx > ,
2481+ universe : ty:: UniverseIndex ,
2482+ }
2483+
2484+ // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder.
2485+ impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for BoundVarEraser < ' tcx > {
2486+ fn interner ( & self ) -> TyCtxt < ' tcx > {
2487+ self . tcx
2488+ }
2489+
2490+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
2491+ if r. is_late_bound ( ) { self . tcx . lifetimes . re_erased } else { r }
2492+ }
2493+
2494+ fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
2495+ match * ty. kind ( ) {
2496+ ty:: Bound ( _, bv) => self . tcx . mk_placeholder ( ty:: PlaceholderType {
2497+ universe : self . universe ,
2498+ bound : bv,
2499+ } ) ,
2500+ _ => ty. super_fold_with ( self ) ,
2501+ }
2502+ }
2503+
2504+ fn fold_const (
2505+ & mut self ,
2506+ ct : ty:: Const < ' tcx > ,
2507+ ) -> <TyCtxt < ' tcx > as rustc_type_ir:: Interner >:: Const {
2508+ assert ! ( !ct. ty( ) . has_escaping_bound_vars( ) ) ;
2509+
2510+ match ct. kind ( ) {
2511+ ty:: ConstKind :: Bound ( _, bv) => self . tcx . mk_const (
2512+ ty:: PlaceholderConst { universe : self . universe , bound : bv } ,
2513+ ct. ty ( ) ,
2514+ ) ,
2515+ _ => ct. super_fold_with ( self ) ,
2516+ }
2517+ }
2518+ }
2519+
2520+ let InferOk { value : self_ty, obligations } =
2521+ infcx. at ( & cause, param_env) . normalize ( self_ty) ;
24852522
24862523 candidates
24872524 . iter ( )
24882525 . copied ( )
24892526 . filter ( |& ( impl_, _) | {
24902527 infcx. probe ( |_| {
24912528 let ocx = ObligationCtxt :: new_in_snapshot ( & infcx) ;
2529+ ocx. register_obligations ( obligations. clone ( ) ) ;
24922530
24932531 let impl_substs = infcx. fresh_substs_for_item ( span, impl_) ;
24942532 let impl_ty = tcx. type_of ( impl_) . subst ( tcx, impl_substs) ;
0 commit comments