@@ -551,69 +551,77 @@ pub fn try_evaluate_const<'tcx>(
551
551
| ty:: ConstKind :: Placeholder ( _)
552
552
| ty:: ConstKind :: Expr ( _) => Err ( EvaluateConstErr :: HasGenericsOrInfers ) ,
553
553
ty:: ConstKind :: Unevaluated ( uv) => {
554
- // Postpone evaluation of constants that depend on generic parameters or inference variables.
555
- let ( args, param_env) = if tcx. features ( ) . generic_const_exprs ( )
556
- && uv. has_non_region_infer ( )
557
- {
558
- // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
559
- // inference variables and generic parameters to show up in `ty::Const` even though the anon const
560
- // does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
561
- match tcx. thir_abstract_const ( uv. def ) {
562
- Ok ( Some ( ct) ) => {
563
- let ct = tcx. expand_abstract_consts ( ct. instantiate ( tcx, uv. args ) ) ;
564
- if let Err ( e) = ct. error_reported ( ) {
565
- return Err ( EvaluateConstErr :: EvaluationFailure ( e) ) ;
566
- } else if ct. has_non_region_infer ( ) || ct. has_non_region_param ( ) {
567
- // If the anon const *does* actually use generic parameters or inference variables from
568
- // the generic arguments provided for it, then we should *not* attempt to evaluate it.
569
- return Err ( EvaluateConstErr :: HasGenericsOrInfers ) ;
570
- } else {
571
- ( replace_param_and_infer_args_with_placeholder ( tcx, uv. args ) , param_env)
572
- }
573
- }
574
- Err ( _) | Ok ( None ) => {
575
- let args = GenericArgs :: identity_for_item ( tcx, uv. def ) ;
576
- let param_env = tcx. param_env ( uv. def ) ;
577
- ( args, param_env)
578
- }
579
- }
580
- } else if tcx. def_kind ( uv. def ) == DefKind :: AnonConst && uv. has_non_region_infer ( ) {
581
- // FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
582
- //
583
- // Diagnostics will sometimes replace the identity args of anon consts in
584
- // array repeat expr counts with inference variables so we have to handle this
585
- // even though it is not something we should ever actually encounter.
586
- //
587
- // Array repeat expr counts are allowed to syntactically use generic parameters
588
- // but must not actually depend on them in order to evalaute succesfully. This means
589
- // that it is actually fine to evalaute them in their own environment rather than with
590
- // the actually provided generic arguments.
591
- tcx. dcx ( ) . delayed_bug (
592
- "Encountered anon const with inference variable args but no error reported" ,
593
- ) ;
594
-
595
- let args = GenericArgs :: identity_for_item ( tcx, uv. def ) ;
596
- let param_env = tcx. param_env ( uv. def ) ;
597
- ( args, param_env)
598
- } else {
599
- // FIXME: This codepath is reachable under `associated_const_equality` and in the
600
- // future will be reachable by `min_generic_const_args`. We should handle inference
601
- // variables and generic parameters properly instead of doing nothing.
602
- ( uv. args , param_env)
603
- } ;
604
- let uv = ty:: UnevaluatedConst :: new ( uv. def , args) ;
605
-
606
- // It's not *technically* correct to be revealing opaque types here as borrowcheck has
607
- // not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
608
- // during typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
554
+ // Postpone evaluation of constants that depend on generic parameters or
555
+ // inference variables.
556
+ //
557
+ // We use `TypingMode::PostAnalysis` here which is not *technically* correct
558
+ // to be revealing opaque types here as borrowcheck has not run yet. However,
559
+ // CTFE itself uses `TypingMode::PostAnalysis` unconditionally even during
560
+ // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
609
561
// As a result we always use a revealed env when resolving the instance to evaluate.
610
562
//
611
563
// FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
612
564
// instead of having this logic here
613
- let typing_env =
614
- tcx. erase_regions ( infcx. typing_env ( param_env) ) . with_post_analysis_normalized ( tcx) ;
615
- let erased_uv = tcx. erase_regions ( uv) ;
565
+ let ( args, typing_env) =
566
+ if tcx. features ( ) . generic_const_exprs ( ) && uv. has_non_region_infer ( ) {
567
+ // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
568
+ // inference variables and generic parameters to show up in `ty::Const` even though the anon const
569
+ // does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
570
+ match tcx. thir_abstract_const ( uv. def ) {
571
+ Ok ( Some ( ct) ) => {
572
+ let ct = tcx. expand_abstract_consts ( ct. instantiate ( tcx, uv. args ) ) ;
573
+ if let Err ( e) = ct. error_reported ( ) {
574
+ return Err ( EvaluateConstErr :: EvaluationFailure ( e) ) ;
575
+ } else if ct. has_non_region_infer ( ) || ct. has_non_region_param ( ) {
576
+ // If the anon const *does* actually use generic parameters or inference variables from
577
+ // the generic arguments provided for it, then we should *not* attempt to evaluate it.
578
+ return Err ( EvaluateConstErr :: HasGenericsOrInfers ) ;
579
+ } else {
580
+ let typing_env = infcx
581
+ . typing_env ( tcx. erase_regions ( param_env) )
582
+ . with_post_analysis_normalized ( tcx) ;
583
+ (
584
+ replace_param_and_infer_args_with_placeholder ( tcx, uv. args ) ,
585
+ typing_env,
586
+ )
587
+ }
588
+ }
589
+ Err ( _) | Ok ( None ) => {
590
+ let args = GenericArgs :: identity_for_item ( tcx, uv. def ) ;
591
+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, uv. def ) ;
592
+ ( args, typing_env)
593
+ }
594
+ }
595
+ } else if tcx. def_kind ( uv. def ) == DefKind :: AnonConst && uv. has_non_region_infer ( ) {
596
+ // FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
597
+ //
598
+ // Diagnostics will sometimes replace the identity args of anon consts in
599
+ // array repeat expr counts with inference variables so we have to handle this
600
+ // even though it is not something we should ever actually encounter.
601
+ //
602
+ // Array repeat expr counts are allowed to syntactically use generic parameters
603
+ // but must not actually depend on them in order to evalaute succesfully. This means
604
+ // that it is actually fine to evalaute them in their own environment rather than with
605
+ // the actually provided generic arguments.
606
+ tcx. dcx ( ) . delayed_bug (
607
+ "Encountered anon const with inference variable args but no error reported" ,
608
+ ) ;
616
609
610
+ let args = GenericArgs :: identity_for_item ( tcx, uv. def ) ;
611
+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, uv. def ) ;
612
+ ( args, typing_env)
613
+ } else {
614
+ // FIXME: This codepath is reachable under `associated_const_equality` and in the
615
+ // future will be reachable by `min_generic_const_args`. We should handle inference
616
+ // variables and generic parameters properly instead of doing nothing.
617
+ let typing_env = infcx
618
+ . typing_env ( tcx. erase_regions ( param_env) )
619
+ . with_post_analysis_normalized ( tcx) ;
620
+ ( uv. args , typing_env)
621
+ } ;
622
+ let uv = ty:: UnevaluatedConst :: new ( uv. def , args) ;
623
+
624
+ let erased_uv = tcx. erase_regions ( uv) ;
617
625
use rustc_middle:: mir:: interpret:: ErrorHandled ;
618
626
match tcx. const_eval_resolve_for_typeck ( typing_env, erased_uv, DUMMY_SP ) {
619
627
Ok ( Ok ( val) ) => Ok ( ty:: Const :: new_value (
0 commit comments