@@ -542,6 +542,9 @@ pub fn try_evaluate_const<'tcx>(
542
542
| ty:: ConstKind :: Placeholder ( _)
543
543
| ty:: ConstKind :: Expr ( _) => Err ( EvaluateConstErr :: HasGenericsOrInfers ) ,
544
544
ty:: ConstKind :: Unevaluated ( uv) => {
545
+ let opt_anon_const_kind =
546
+ ( tcx. def_kind ( uv. def ) == DefKind :: AnonConst ) . then_some ( tcx. anon_const_kind ( uv. def ) ) ;
547
+
545
548
// Postpone evaluation of constants that depend on generic parameters or
546
549
// inference variables.
547
550
//
@@ -553,87 +556,86 @@ pub fn try_evaluate_const<'tcx>(
553
556
//
554
557
// FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
555
558
// instead of having this logic here
556
- let ( args, typing_env) = if tcx. def_kind ( uv. def ) == DefKind :: AnonConst
557
- && let ty:: AnonConstKind :: GCEConst = tcx. anon_const_kind ( uv. def )
558
- {
559
+ let ( args, typing_env) = match opt_anon_const_kind {
559
560
// We handle `generic_const_exprs` separately as reasonable ways of handling constants in the type system
560
561
// completely fall apart under `generic_const_exprs` and makes this whole function Really hard to reason
561
562
// about if you have to consider gce whatsoever.
562
-
563
- if uv. has_non_region_infer ( ) || uv. has_non_region_param ( ) {
564
- // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
565
- // inference variables and generic parameters to show up in `ty::Const` even though the anon const
566
- // does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
567
- match tcx. thir_abstract_const ( uv. def ) {
568
- Ok ( Some ( ct) ) => {
569
- let ct = tcx. expand_abstract_consts ( ct. instantiate ( tcx, uv. args ) ) ;
570
- if let Err ( e) = ct. error_reported ( ) {
571
- return Err ( EvaluateConstErr :: EvaluationFailure ( e) ) ;
572
- } else if ct. has_non_region_infer ( ) || ct. has_non_region_param ( ) {
573
- // If the anon const *does* actually use generic parameters or inference variables from
574
- // the generic arguments provided for it, then we should *not* attempt to evaluate it.
575
- return Err ( EvaluateConstErr :: HasGenericsOrInfers ) ;
576
- } else {
577
- let args =
578
- replace_param_and_infer_args_with_placeholder ( tcx, uv. args ) ;
579
- let typing_env = infcx
580
- . typing_env ( tcx. erase_regions ( param_env) )
581
- . with_post_analysis_normalized ( tcx) ;
563
+ Some ( ty:: AnonConstKind :: GCE ) => {
564
+ if uv. has_non_region_infer ( ) || uv. has_non_region_param ( ) {
565
+ // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
566
+ // inference variables and generic parameters to show up in `ty::Const` even though the anon const
567
+ // does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
568
+ match tcx. thir_abstract_const ( uv. def ) {
569
+ Ok ( Some ( ct) ) => {
570
+ let ct = tcx. expand_abstract_consts ( ct. instantiate ( tcx, uv. args ) ) ;
571
+ if let Err ( e) = ct. error_reported ( ) {
572
+ return Err ( EvaluateConstErr :: EvaluationFailure ( e) ) ;
573
+ } else if ct. has_non_region_infer ( ) || ct. has_non_region_param ( ) {
574
+ // If the anon const *does* actually use generic parameters or inference variables from
575
+ // the generic arguments provided for it, then we should *not* attempt to evaluate it.
576
+ return Err ( EvaluateConstErr :: HasGenericsOrInfers ) ;
577
+ } else {
578
+ let args =
579
+ replace_param_and_infer_args_with_placeholder ( tcx, uv. args ) ;
580
+ let typing_env = infcx
581
+ . typing_env ( tcx. erase_regions ( param_env) )
582
+ . with_post_analysis_normalized ( tcx) ;
583
+ ( args, typing_env)
584
+ }
585
+ }
586
+ Err ( _) | Ok ( None ) => {
587
+ let args = GenericArgs :: identity_for_item ( tcx, uv. def ) ;
588
+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, uv. def ) ;
582
589
( args, typing_env)
583
590
}
584
591
}
585
- Err ( _ ) | Ok ( None ) => {
586
- let args = GenericArgs :: identity_for_item ( tcx , uv . def ) ;
587
- let typing_env = ty :: TypingEnv :: post_analysis ( tcx, uv . def ) ;
588
- ( args , typing_env )
589
- }
592
+ } else {
593
+ let typing_env = infcx
594
+ . typing_env ( tcx. erase_regions ( param_env ) )
595
+ . with_post_analysis_normalized ( tcx ) ;
596
+ ( uv . args , typing_env )
590
597
}
591
- } else {
592
- let typing_env = infcx
593
- . typing_env ( tcx. erase_regions ( param_env) )
594
- . with_post_analysis_normalized ( tcx) ;
595
- ( uv. args , typing_env)
596
598
}
597
- } else if tcx. def_kind ( uv. def ) == DefKind :: AnonConst
598
- && let ty:: AnonConstKind :: RepeatExprCount = tcx. anon_const_kind ( uv. def )
599
- {
600
- if uv. has_non_region_infer ( ) {
601
- // Diagnostics will sometimes replace the identity args of anon consts in
602
- // array repeat expr counts with inference variables so we have to handle this
603
- // even though it is not something we should ever actually encounter.
604
- //
605
- // Array repeat expr counts are allowed to syntactically use generic parameters
606
- // but must not actually depend on them in order to evalaute successfully. This means
607
- // that it is actually fine to evalaute them in their own environment rather than with
608
- // the actually provided generic arguments.
609
- tcx. dcx ( ) . delayed_bug (
599
+ Some ( ty:: AnonConstKind :: RepeatExprCount ) => {
600
+ if uv. has_non_region_infer ( ) {
601
+ // Diagnostics will sometimes replace the identity args of anon consts in
602
+ // array repeat expr counts with inference variables so we have to handle this
603
+ // even though it is not something we should ever actually encounter.
604
+ //
605
+ // Array repeat expr counts are allowed to syntactically use generic parameters
606
+ // but must not actually depend on them in order to evalaute successfully. This means
607
+ // that it is actually fine to evalaute them in their own environment rather than with
608
+ // the actually provided generic arguments.
609
+ tcx. dcx ( ) . delayed_bug (
610
610
"Encountered anon const with inference variable args but no error reported" ,
611
611
) ;
612
- }
612
+ }
613
613
614
- // The generic args of repeat expr counts under `min_const_generics` are not supposed to
615
- // affect evaluation of the constant as this would make it a "truly" generic const arg.
616
- // To prevent this we discard all the generic arguments and evalaute with identity args
617
- // and in its own environment instead of the current environment we are normalizing in.
618
- let args = GenericArgs :: identity_for_item ( tcx, uv. def ) ;
619
- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, uv. def ) ;
614
+ // The generic args of repeat expr counts under `min_const_generics` are not supposed to
615
+ // affect evaluation of the constant as this would make it a "truly" generic const arg.
616
+ // To prevent this we discard all the generic arguments and evalaute with identity args
617
+ // and in its own environment instead of the current environment we are normalizing in.
618
+ let args = GenericArgs :: identity_for_item ( tcx, uv. def ) ;
619
+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, uv. def ) ;
620
620
621
- ( args, typing_env)
622
- } else {
623
- // We are only dealing with "truly" generic/uninferred constants here:
624
- // - GCEConsts have been handled separately
625
- // - Repeat expr count back compat consts have also been handled separately
626
- // So we are free to simply defer evaluation here.
627
- //
628
- // FIXME: This assumes that `args` are normalized which is not necessarily true
629
- if uv. args . has_non_region_param ( ) || uv. args . has_non_region_infer ( ) {
630
- return Err ( EvaluateConstErr :: HasGenericsOrInfers ) ;
621
+ ( args, typing_env)
631
622
}
623
+ _ => {
624
+ // We are only dealing with "truly" generic/uninferred constants here:
625
+ // - GCEConsts have been handled separately
626
+ // - Repeat expr count back compat consts have also been handled separately
627
+ // So we are free to simply defer evaluation here.
628
+ //
629
+ // FIXME: This assumes that `args` are normalized which is not necessarily true
630
+ if uv. args . has_non_region_param ( ) || uv. args . has_non_region_infer ( ) {
631
+ return Err ( EvaluateConstErr :: HasGenericsOrInfers ) ;
632
+ }
632
633
633
- let typing_env = infcx
634
- . typing_env ( tcx. erase_regions ( param_env) )
635
- . with_post_analysis_normalized ( tcx) ;
636
- ( uv. args , typing_env)
634
+ let typing_env = infcx
635
+ . typing_env ( tcx. erase_regions ( param_env) )
636
+ . with_post_analysis_normalized ( tcx) ;
637
+ ( uv. args , typing_env)
638
+ }
637
639
} ;
638
640
639
641
let uv = ty:: UnevaluatedConst :: new ( uv. def , args) ;
0 commit comments