@@ -549,9 +549,17 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
549549 ty:: AliasTermKind :: InherentTy { def_id } => {
550550 tcx. type_of ( def_id) . instantiate ( tcx, args) . skip_norm_wip ( ) . into ( )
551551 }
552- ty:: AliasTermKind :: InherentConst { def_id } => {
552+ ty:: AliasTermKind :: InherentConst { def_id } if tcx . is_type_const ( def_id ) => {
553553 tcx. const_of_item ( def_id) . instantiate ( tcx, args) . skip_norm_wip ( ) . into ( )
554554 }
555+ ty:: AliasTermKind :: InherentConst { .. } => {
556+ // FIXME(gca): This is dead code at the moment. It should eventually call
557+ // super::evaluate_const like projected consts do in confirm_impl_candidate in this
558+ // file. However, how generic args are represented for IACs is up in the air right now.
559+ // Will super::evaluate_const eventually take the inherent_args or the impl_args form of
560+ // args? It might be either.
561+ panic ! ( "References to inherent associated consts should have been blocked" ) ;
562+ }
555563 kind => panic ! ( "expected inherent alias, found {kind:?}" ) ,
556564 } ;
557565
@@ -617,11 +625,13 @@ pub fn compute_inherent_assoc_term_args<'a, 'b, 'tcx>(
617625 alias_term. rebase_inherent_args_onto_impl ( impl_args, tcx)
618626}
619627
628+ #[ derive( Debug ) ]
620629enum Projected < ' tcx > {
621630 Progress ( Progress < ' tcx > ) ,
622631 NoProgress ( ty:: Term < ' tcx > ) ,
623632}
624633
634+ #[ derive( Debug ) ]
625635struct Progress < ' tcx > {
626636 term : ty:: Term < ' tcx > ,
627637 obligations : PredicateObligations < ' tcx > ,
@@ -652,7 +662,7 @@ impl<'tcx> Progress<'tcx> {
652662/// IMPORTANT:
653663/// - `obligation` must be fully normalized
654664// FIXME(mgca): While this supports constants, it is only used for types by default right now
655- #[ instrument( level = "info" , skip( selcx) ) ]
665+ #[ instrument( level = "info" , ret , skip( selcx) ) ]
656666fn project < ' cx , ' tcx > (
657667 selcx : & mut SelectionContext < ' cx , ' tcx > ,
658668 obligation : & ProjectionTermObligation < ' tcx > ,
@@ -2060,7 +2070,21 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20602070 ty:: AliasTermKind :: ProjectionConst { .. } => {
20612071 let uv = ty:: UnevaluatedConst :: new ( assoc_term. item . def_id , args) ;
20622072 let ct = ty:: Const :: new_unevaluated ( tcx, uv) ;
2063- super :: evaluate_const ( selcx. infcx , ct, param_env) . into ( )
2073+ // We don't want to use super::evaluate_const, because that returns its parameter
2074+ // unchanged if it is too generic to evaluate. We are passing the `impl` form of the
2075+ // constant to evaluate_const (with generic arguments corresponding to the impl
2076+ // block), but we want to return the original, non-rebased, trait `Self` form of the
2077+ // constant (with generic arguments being the trait `Self` type) in Projected::NoProgress.
2078+ match super :: try_evaluate_const ( selcx. infcx , ct, param_env) {
2079+ Ok ( evaluated) => evaluated. into ( ) ,
2080+ Err (
2081+ super :: EvaluateConstErr :: EvaluationFailure ( e)
2082+ | super :: EvaluateConstErr :: InvalidConstParamTy ( e) ,
2083+ ) => ty:: Const :: new_error ( tcx, e) . into ( ) ,
2084+ Err ( super :: EvaluateConstErr :: HasGenericsOrInfers ) => {
2085+ return Ok ( Projected :: NoProgress ( obligation. predicate . to_term ( tcx) ) ) ;
2086+ }
2087+ }
20642088 }
20652089 kind => panic ! ( "expected projection alias, found {kind:?}" ) ,
20662090 } ;
0 commit comments