@@ -542,6 +542,9 @@ pub fn try_evaluate_const<'tcx>(
542542        | ty:: ConstKind :: Placeholder ( _) 
543543        | ty:: ConstKind :: Expr ( _)  => Err ( EvaluateConstErr :: HasGenericsOrInfers ) , 
544544        ty:: ConstKind :: Unevaluated ( uv)  => { 
545+             let  opt_anon_const_kind =
546+                 ( tcx. def_kind ( uv. def )  == DefKind :: AnonConst ) . then ( || tcx. anon_const_kind ( uv. def ) ) ; 
547+ 
545548            // Postpone evaluation of constants that depend on generic parameters or 
546549            // inference variables. 
547550            // 
@@ -553,87 +556,90 @@ pub fn try_evaluate_const<'tcx>(
553556            // 
554557            // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself 
555558            // 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 { 
559560                // We handle `generic_const_exprs` separately as reasonable ways of handling constants in the type system 
560561                // completely fall apart under `generic_const_exprs` and makes this whole function Really hard to reason 
561562                // 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 ) ; 
582589                                ( args,  typing_env) 
583590                            } 
584591                        } 
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 ) 
590597                    } 
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-                 } 
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 ( 
610-                         "Encountered anon const with inference variable args but no error reported" , 
611-                     ) ; 
612598                } 
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 ( "AnonConst with infer args but no error reported" ) ; 
610+                     } 
613611
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 ) ; 
612+                      // The generic args of repeat expr counts under `min_const_generics` are not supposed to 
613+                      // affect evaluation of the constant as this would make it a "truly" generic const arg. 
614+                      // To prevent this we discard all the generic arguments and evalaute with identity args 
615+                      // and in its own environment instead of the current environment we are normalizing in. 
616+                      let  args = GenericArgs :: identity_for_item ( tcx,  uv. def ) ; 
617+                      let  typing_env = ty:: TypingEnv :: post_analysis ( tcx,  uv. def ) ; 
620618
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 ) ; 
619+                     ( args,  typing_env) 
631620                } 
621+                 _ => { 
622+                     // We are only dealing with "truly" generic/uninferred constants here: 
623+                     // - GCEConsts have been handled separately 
624+                     // - Repeat expr count back compat consts have also been handled separately 
625+                     // So we are free to simply defer evaluation here. 
626+                     // 
627+                     // FIXME: This assumes that `args` are normalized which is not necessarily true 
628+                     // 
629+                     // Const patterns are converted to type system constants before being 
630+                     // evaluated. However, we don't care about them here as pattern evaluation 
631+                     // logic does not go through type system normalization. If it did this would 
632+                     // be a backwards compatibility problem as we do not enforce "syntactic" non- 
633+                     // usage of generic parameters like we do here. 
634+                     if  uv. args . has_non_region_param ( )  || uv. args . has_non_region_infer ( )  { 
635+                         return  Err ( EvaluateConstErr :: HasGenericsOrInfers ) ; 
636+                     } 
632637
633-                 let  typing_env = infcx
634-                     . typing_env ( tcx. erase_regions ( param_env) ) 
635-                     . with_post_analysis_normalized ( tcx) ; 
636-                 ( uv. args ,  typing_env) 
638+                     let  typing_env = infcx
639+                         . typing_env ( tcx. erase_regions ( param_env) ) 
640+                         . with_post_analysis_normalized ( tcx) ; 
641+                     ( uv. args ,  typing_env) 
642+                 } 
637643            } ; 
638644
639645            let  uv = ty:: UnevaluatedConst :: new ( uv. def ,  args) ; 
0 commit comments