Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b4079c6

Browse files
committed
Don't evaluate constants depending on infers or params
1 parent 996a185 commit b4079c6

File tree

1 file changed

+64
-42
lines changed
  • compiler/rustc_trait_selection/src/traits

1 file changed

+64
-42
lines changed

‎compiler/rustc_trait_selection/src/traits/mod.rs‎

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ pub fn try_evaluate_const<'tcx>(
545545
// Postpone evaluation of constants that depend on generic parameters or
546546
// inference variables.
547547
//
548-
// We use `TypingMode::PostAnalysis` here which is not *technically* correct
548+
// We use `TypingMode::PostAnalysis` here which is not *technically* correct
549549
// to be revealing opaque types here as borrowcheck has not run yet. However,
550550
// CTFE itself uses `TypingMode::PostAnalysis` unconditionally even during
551551
// typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
@@ -555,68 +555,90 @@ pub fn try_evaluate_const<'tcx>(
555555
// instead of having this logic here
556556
let (args, typing_env) = if tcx.def_kind(uv.def) == DefKind::AnonConst
557557
&& let ty::AnonConstKind::GCEConst = tcx.anon_const_kind(uv.def)
558-
&& uv.has_non_region_infer()
559558
{
560-
// `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
561-
// inference variables and generic parameters to show up in `ty::Const` even though the anon const
562-
// does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
563-
match tcx.thir_abstract_const(uv.def) {
564-
Ok(Some(ct)) => {
565-
let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, uv.args));
566-
if let Err(e) = ct.error_reported() {
567-
return Err(EvaluateConstErr::EvaluationFailure(e));
568-
} else if ct.has_non_region_infer() || ct.has_non_region_param() {
569-
// If the anon const *does* actually use generic parameters or inference variables from
570-
// the generic arguments provided for it, then we should *not* attempt to evaluate it.
571-
return Err(EvaluateConstErr::HasGenericsOrInfers);
572-
} else {
573-
let args = replace_param_and_infer_args_with_placeholder(tcx, uv.args);
574-
let typing_env = infcx
575-
.typing_env(tcx.erase_regions(param_env))
576-
.with_post_analysis_normalized(tcx);
559+
// We handle `generic_const_exprs` separately as reasonable ways of handling constants in the type system
560+
// completely fall apart under `generic_const_exprs` and makes this whole function Really hard to reason
561+
// 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);
582+
(args, typing_env)
583+
}
584+
}
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);
577588
(args, typing_env)
578589
}
579590
}
580-
Err(_) | Ok(None) => {
581-
let args = GenericArgs::identity_for_item(tcx, uv.def);
582-
lettyping_env = ty::TypingEnv::post_analysis(tcx, uv.def);
583-
(args, typing_env)
584-
}
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)
585596
}
586597
} else if tcx.def_kind(uv.def) == DefKind::AnonConst
587598
&& let ty::AnonConstKind::RepeatExprCount = tcx.anon_const_kind(uv.def)
588-
&& uv.has_non_region_infer()
589599
{
590-
// FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
591-
//
592-
// Diagnostics will sometimes replace the identity args of anon consts in
593-
// array repeat expr counts with inference variables so we have to handle this
594-
// even though it is not something we should ever actually encounter.
595-
//
596-
// Array repeat expr counts are allowed to syntactically use generic parameters
597-
// but must not actually depend on them in order to evalaute successfully. This means
598-
// that it is actually fine to evalaute them in their own environment rather than with
599-
// the actually provided generic arguments.
600-
tcx.dcx().delayed_bug(
601-
"Encountered anon const with inference variable args but no error reported",
602-
);
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+
);
612+
}
603613

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.
604618
let args = GenericArgs::identity_for_item(tcx, uv.def);
605619
let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
606620

607621
(args, typing_env)
608622
} else {
609-
// FIXME: This codepath is reachable under `associated_const_equality` and in the
610-
// future will be reachable by `min_generic_const_args`. We should handle inference
611-
// variables and generic parameters properly instead of doing nothing.
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);
631+
}
632+
612633
let typing_env = infcx
613634
.typing_env(tcx.erase_regions(param_env))
614635
.with_post_analysis_normalized(tcx);
615636
(uv.args, typing_env)
616637
};
617-
let uv = ty::UnevaluatedConst::new(uv.def, args);
618638

639+
let uv = ty::UnevaluatedConst::new(uv.def, args);
619640
let erased_uv = tcx.erase_regions(uv);
641+
620642
use rustc_middle::mir::interpret::ErrorHandled;
621643
match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) {
622644
Ok(Ok(val)) => Ok(ty::Const::new_value(

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /