@@ -2419,6 +2419,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24192419 return Ok ( None ) ;
24202420 }
24212421
2422+ //
2423+ // Select applicable inherent associated type candidates modulo regions.
2424+ //
2425+
24222426 // In contexts that have no inference context, just make a new one.
24232427 // We do need a local variable to store it, though.
24242428 let infcx_;
@@ -2431,14 +2435,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24312435 }
24322436 } ;
24332437
2434- let param_env = tcx. param_env ( block. owner . to_def_id ( ) ) ;
2438+ // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
2439+ // when inside of an ADT (#108491) or where clause.
2440+ let param_env = tcx. param_env ( block. owner ) ;
24352441 let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
24362442
24372443 let mut fulfillment_errors = Vec :: new ( ) ;
24382444 let mut applicable_candidates: Vec < _ > = infcx. probe ( |_| {
24392445 let universe = infcx. create_next_universe ( ) ;
24402446
24412447 // Regions are not considered during selection.
2448+ // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes
2449+ // of type and const binders. Is that correct in the selection phase? See also #109505.
24422450 let self_ty = tcx. replace_escaping_bound_vars_uncached (
24432451 self_ty,
24442452 FnMutDelegate {
@@ -2454,41 +2462,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24542462
24552463 candidates
24562464 . iter ( )
2457- . filter_map ( |& ( impl_, ( assoc_item, def_scope) ) | {
2465+ . copied ( )
2466+ . filter ( |& ( impl_, _) | {
24582467 infcx. probe ( |_| {
24592468 let ocx = ObligationCtxt :: new_in_snapshot ( & infcx) ;
24602469
2461- let impl_ty = tcx. type_of ( impl_) ;
24622470 let impl_substs = infcx. fresh_item_substs ( impl_) ;
2463- let impl_ty = impl_ty . subst ( tcx, impl_substs) ;
2471+ let impl_ty = tcx . type_of ( impl_ ) . subst ( tcx, impl_substs) ;
24642472 let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
24652473
2466- // Check that the Self-types can be related.
2467- // FIXME(fmease): Should we use `eq` here?
2468- ocx. sup ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . ok ( ) ?;
2474+ // Check that the self types can be related.
2475+ // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
2476+ // `sup` for this situtation, too. What for? To constrain inference variables?
2477+ if ocx. sup ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( )
2478+ {
2479+ return false ;
2480+ }
24692481
24702482 // Check whether the impl imposes obligations we have to worry about.
2471- let impl_bounds = tcx. predicates_of ( impl_) ;
2472- let impl_bounds = impl_bounds. instantiate ( tcx, impl_substs) ;
2473-
2483+ let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_substs) ;
24742484 let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
2475-
24762485 let impl_obligations = traits:: predicates_for_generics (
24772486 |_, _| cause. clone ( ) ,
24782487 param_env,
24792488 impl_bounds,
24802489 ) ;
2481-
24822490 ocx. register_obligations ( impl_obligations) ;
24832491
24842492 let mut errors = ocx. select_where_possible ( ) ;
24852493 if !errors. is_empty ( ) {
24862494 fulfillment_errors. append ( & mut errors) ;
2487- return None ;
2495+ return false ;
24882496 }
24892497
2490- // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2491- Some ( ( assoc_item, def_scope, infcx. resolve_vars_if_possible ( impl_substs) ) )
2498+ true
24922499 } )
24932500 } )
24942501 . collect ( )
@@ -2497,24 +2504,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24972504 if applicable_candidates. len ( ) > 1 {
24982505 return Err ( self . complain_about_ambiguous_inherent_assoc_type (
24992506 name,
2500- applicable_candidates. into_iter ( ) . map ( |( candidate, .. ) | candidate) . collect ( ) ,
2507+ applicable_candidates. into_iter ( ) . map ( |( _ , ( candidate, _ ) ) | candidate) . collect ( ) ,
25012508 span,
25022509 ) ) ;
25032510 }
25042511
2505- if let Some ( ( assoc_item , def_scope , impl_substs ) ) = applicable_candidates. pop ( ) {
2512+ if let Some ( ( impl_ , ( assoc_item , def_scope ) ) ) = applicable_candidates. pop ( ) {
25062513 self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
25072514
2508- // FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate, we still
2509- // need to relate the Self-type with fresh item substs & register region obligations for
2510- // regionck to prove/disprove.
2511-
2512- let item_substs =
2513- self . create_substs_for_associated_item ( span, assoc_item, segment, impl_substs) ;
2515+ // FIXME(fmease): Currently creating throwaway `parent_substs` to please
2516+ // `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to
2517+ // not require the parent substs logic.
2518+ let parent_substs = InternalSubsts :: identity_for_item ( tcx, impl_) ;
2519+ let substs =
2520+ self . create_substs_for_associated_item ( span, assoc_item, segment, parent_substs) ;
2521+ let substs = tcx. mk_substs_from_iter (
2522+ std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
2523+ . chain ( substs. into_iter ( ) . skip ( parent_substs. len ( ) ) ) ,
2524+ ) ;
25142525
2515- // FIXME(fmease, #106722): Check if the bounds on the parameters of the
2516- // associated type hold, if any.
2517- let ty = tcx. type_of ( assoc_item) . subst ( tcx, item_substs) ;
2526+ let ty = tcx. mk_alias ( ty:: Inherent , tcx. mk_alias_ty ( assoc_item, substs) ) ;
25182527
25192528 return Ok ( Some ( ( ty, assoc_item) ) ) ;
25202529 }
0 commit comments