@@ -26,10 +26,9 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
26
26
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
27
27
use rustc_hir:: intravisit:: { walk_generics, Visitor as _} ;
28
28
use rustc_hir:: { GenericArg , GenericArgs , OpaqueTyOrigin } ;
29
- use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
29
+ use rustc_infer:: infer:: { InferCtxt , InferOk , TyCtxtInferExt } ;
30
30
use rustc_infer:: traits:: ObligationCause ;
31
31
use rustc_middle:: middle:: stability:: AllowUnstable ;
32
- use rustc_middle:: ty:: fold:: FnMutDelegate ;
33
32
use rustc_middle:: ty:: subst:: { self , GenericArgKind , InternalSubsts , SubstsRef } ;
34
33
use rustc_middle:: ty:: GenericParamDefKind ;
35
34
use rustc_middle:: ty:: { self , Const , IsSuggestable , Ty , TyCtxt , TypeVisitableExt } ;
@@ -43,7 +42,10 @@ use rustc_trait_selection::traits::error_reporting::{
43
42
report_object_safety_error, suggestions:: NextTypeParamName ,
44
43
} ;
45
44
use 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 } ;
47
49
48
50
use smallvec:: { smallvec, SmallVec } ;
49
51
use std:: collections:: BTreeSet ;
@@ -2442,6 +2444,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2442
2444
return Ok ( None ) ;
2443
2445
}
2444
2446
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
+
2445
2452
//
2446
2453
// Select applicable inherent associated type candidates modulo regions.
2447
2454
//
@@ -2465,30 +2472,61 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2465
2472
2466
2473
let mut fulfillment_errors = Vec :: new ( ) ;
2467
2474
let mut applicable_candidates: Vec < _ > = infcx. probe ( |_| {
2468
- let universe = infcx. create_next_universe ( ) ;
2469
-
2470
2475
// 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) ;
2485
2522
2486
2523
candidates
2487
2524
. iter ( )
2488
2525
. copied ( )
2489
2526
. filter ( |& ( impl_, _) | {
2490
2527
infcx. probe ( |_| {
2491
2528
let ocx = ObligationCtxt :: new_in_snapshot ( & infcx) ;
2529
+ ocx. register_obligations ( obligations. clone ( ) ) ;
2492
2530
2493
2531
let impl_substs = infcx. fresh_substs_for_item ( span, impl_) ;
2494
2532
let impl_ty = tcx. type_of ( impl_) . subst ( tcx, impl_substs) ;
0 commit comments