@@ -2378,6 +2378,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2378
2378
return Ok ( None ) ;
2379
2379
}
2380
2380
2381
+ //
2382
+ // Select applicable inherent associated type candidates modulo regions.
2383
+ //
2384
+
2381
2385
// In contexts that have no inference context, just make a new one.
2382
2386
// We do need a local variable to store it, though.
2383
2387
let infcx_;
@@ -2390,14 +2394,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2390
2394
}
2391
2395
} ;
2392
2396
2393
- let param_env = tcx. param_env ( block. owner . to_def_id ( ) ) ;
2397
+ // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
2398
+ // when inside of an ADT (#108491) or where clause.
2399
+ let param_env = tcx. param_env ( block. owner ) ;
2394
2400
let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
2395
2401
2396
2402
let mut fulfillment_errors = Vec :: new ( ) ;
2397
2403
let mut applicable_candidates: Vec < _ > = infcx. probe ( |_| {
2398
2404
let universe = infcx. create_next_universe ( ) ;
2399
2405
2400
2406
// Regions are not considered during selection.
2407
+ // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes
2408
+ // of type and const binders. Is that correct in the selection phase? See also #109505.
2401
2409
let self_ty = tcx. replace_escaping_bound_vars_uncached (
2402
2410
self_ty,
2403
2411
FnMutDelegate {
@@ -2413,41 +2421,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2413
2421
2414
2422
candidates
2415
2423
. iter ( )
2416
- . filter_map ( |& ( impl_, ( assoc_item, def_scope) ) | {
2424
+ . copied ( )
2425
+ . filter ( |& ( impl_, _) | {
2417
2426
infcx. probe ( |_| {
2418
2427
let ocx = ObligationCtxt :: new_in_snapshot ( & infcx) ;
2419
2428
2420
- let impl_ty = tcx. type_of ( impl_) ;
2421
2429
let impl_substs = infcx. fresh_item_substs ( impl_) ;
2422
- let impl_ty = impl_ty . subst ( tcx, impl_substs) ;
2430
+ let impl_ty = tcx . type_of ( impl_ ) . subst ( tcx, impl_substs) ;
2423
2431
let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
2424
2432
2425
- // Check that the Self-types can be related.
2426
- // FIXME(fmease): Should we use `eq` here?
2427
- ocx. sup ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . ok ( ) ?;
2433
+ // Check that the self types can be related.
2434
+ // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
2435
+ // `sup` for this situtation, too. What for? To constrain inference variables?
2436
+ if ocx. sup ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( )
2437
+ {
2438
+ return false ;
2439
+ }
2428
2440
2429
2441
// Check whether the impl imposes obligations we have to worry about.
2430
- let impl_bounds = tcx. predicates_of ( impl_) ;
2431
- let impl_bounds = impl_bounds. instantiate ( tcx, impl_substs) ;
2432
-
2442
+ let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_substs) ;
2433
2443
let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
2434
-
2435
2444
let impl_obligations = traits:: predicates_for_generics (
2436
2445
|_, _| cause. clone ( ) ,
2437
2446
param_env,
2438
2447
impl_bounds,
2439
2448
) ;
2440
-
2441
2449
ocx. register_obligations ( impl_obligations) ;
2442
2450
2443
2451
let mut errors = ocx. select_where_possible ( ) ;
2444
2452
if !errors. is_empty ( ) {
2445
2453
fulfillment_errors. append ( & mut errors) ;
2446
- return None ;
2454
+ return false ;
2447
2455
}
2448
2456
2449
- // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2450
- Some ( ( assoc_item, def_scope, infcx. resolve_vars_if_possible ( impl_substs) ) )
2457
+ true
2451
2458
} )
2452
2459
} )
2453
2460
. collect ( )
@@ -2456,24 +2463,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2456
2463
if applicable_candidates. len ( ) > 1 {
2457
2464
return Err ( self . complain_about_ambiguous_inherent_assoc_type (
2458
2465
name,
2459
- applicable_candidates. into_iter ( ) . map ( |( candidate, .. ) | candidate) . collect ( ) ,
2466
+ applicable_candidates. into_iter ( ) . map ( |( _ , ( candidate, _ ) ) | candidate) . collect ( ) ,
2460
2467
span,
2461
2468
) ) ;
2462
2469
}
2463
2470
2464
- if let Some ( ( assoc_item , def_scope , impl_substs ) ) = applicable_candidates. pop ( ) {
2471
+ if let Some ( ( impl_ , ( assoc_item , def_scope ) ) ) = applicable_candidates. pop ( ) {
2465
2472
self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
2466
2473
2467
- // FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate, we still
2468
- // need to relate the Self-type with fresh item substs & register region obligations for
2469
- // regionck to prove/disprove.
2470
-
2471
- let item_substs =
2472
- self . create_substs_for_associated_item ( span, assoc_item, segment, impl_substs) ;
2474
+ // FIXME(fmease): Currently creating throwaway `parent_substs` to please
2475
+ // `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to
2476
+ // not require the parent substs logic.
2477
+ let parent_substs = InternalSubsts :: identity_for_item ( tcx, impl_) ;
2478
+ let substs =
2479
+ self . create_substs_for_associated_item ( span, assoc_item, segment, parent_substs) ;
2480
+ let substs = tcx. mk_substs_from_iter (
2481
+ std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
2482
+ . chain ( substs. into_iter ( ) . skip ( parent_substs. len ( ) ) ) ,
2483
+ ) ;
2473
2484
2474
- // FIXME(fmease, #106722): Check if the bounds on the parameters of the
2475
- // associated type hold, if any.
2476
- let ty = tcx. type_of ( assoc_item) . subst ( tcx, item_substs) ;
2485
+ let ty = tcx. mk_alias ( ty:: Inherent , tcx. mk_alias_ty ( assoc_item, substs) ) ;
2477
2486
2478
2487
return Ok ( Some ( ( ty, assoc_item) ) ) ;
2479
2488
}
0 commit comments