Skip to content

Commit 42f9d9a

Browse files
committed
Review Comments
1 parent 22404d9 commit 42f9d9a

File tree

5 files changed

+83
-77
lines changed

5 files changed

+83
-77
lines changed

compiler/rustc_hir_analysis/src/collect.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1836,9 +1836,9 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
18361836
match tcx.hir_node(const_arg_id) {
18371837
hir::Node::ConstArg(_) => {
18381838
if tcx.features().generic_const_exprs() {
1839-
ty::AnonConstKind::GCEConst
1839+
ty::AnonConstKind::GCE
18401840
} else if tcx.features().min_generic_const_args() {
1841-
ty::AnonConstKind::MCGConst
1841+
ty::AnonConstKind::MCG
18421842
} else if let hir::Node::Expr(hir::Expr {
18431843
kind: hir::ExprKind::Repeat(_, repeat_count),
18441844
..
@@ -1847,7 +1847,7 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
18471847
{
18481848
ty::AnonConstKind::RepeatExprCount
18491849
} else {
1850-
ty::AnonConstKind::MCGConst
1850+
ty::AnonConstKind::MCG
18511851
}
18521852
}
18531853
_ => ty::AnonConstKind::NonTypeSystem,

compiler/rustc_hir_analysis/src/collect/generics_of.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
106106

107107
match tcx.anon_const_kind(def_id) {
108108
// Stable: anon consts are not able to use any generic parameters...
109-
ty::AnonConstKind::MCGConst => None,
109+
ty::AnonConstKind::MCG => None,
110110
// we provide generics to repeat expr counts as a backwards compatibility hack. #76200
111111
ty::AnonConstKind::RepeatExprCount => Some(parent_did),
112112

@@ -116,13 +116,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
116116
// We could potentially mirror the hack done for defaults of generic parameters but
117117
// this case just doesn't come up much compared to `const N: u32 = ...`. Long term the
118118
// hack for defaulted parameters should be removed eventually anyway.
119-
ty::AnonConstKind::GCEConst if in_param_ty => None,
119+
ty::AnonConstKind::GCE if in_param_ty => None,
120120
// GCE anon consts as a default for a generic parameter should have their provided generics
121121
// "truncated" up to whatever generic parameter this anon const is within the default of.
122122
//
123123
// FIXME(generic_const_exprs): This only handles `const N: usize = /*defid*/` but not type
124124
// parameter defaults, e.g. `T = Foo</*defid*/>`.
125-
ty::AnonConstKind::GCEConst
125+
ty::AnonConstKind::GCE
126126
if let Some(param_id) =
127127
tcx.hir_opt_const_param_default_param_def_id(hir_id) =>
128128
{
@@ -169,7 +169,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
169169
has_late_bound_regions: generics.has_late_bound_regions,
170170
};
171171
}
172-
ty::AnonConstKind::GCEConst => Some(parent_did),
172+
ty::AnonConstKind::GCE => Some(parent_did),
173173

174174
// Field defaults are allowed to use generic parameters, e.g. `field: u32 = /*defid: N + 1*/`
175175
ty::AnonConstKind::NonTypeSystem

compiler/rustc_middle/src/query/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2579,7 +2579,6 @@ rustc_queries! {
25792579

25802580
query anon_const_kind(def_id: DefId) -> ty::AnonConstKind {
25812581
desc { |tcx| "looking up anon const kind of `{}`", tcx.def_path_str(def_id) }
2582-
cache_on_disk_if { def_id.is_local() }
25832582
separate_provide_extern
25842583
}
25852584
}

compiler/rustc_middle/src/ty/consts.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,13 @@ impl<'tcx> Const<'tcx> {
262262

263263
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable, HashStable)]
264264
pub enum AnonConstKind {
265-
GCEConst,
266-
MCGConst,
265+
/// `feature(generic_const_exprs)` anon consts are allowed to use arbitrary generic parameters in scope
266+
GCE,
267+
/// stable `min_const_generics` anon consts are not allowed to use any generic parameters
268+
MCG,
269+
/// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters
270+
/// but must not depend on the actual instantiation. See #76200 for more information
267271
RepeatExprCount,
272+
/// anon consts outside of the type system, e.g. enum discriminants
268273
NonTypeSystem,
269274
}

compiler/rustc_trait_selection/src/traits/mod.rs

+69-67
Original file line numberDiff line numberDiff line change
@@ -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_some(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,86 @@ 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)
596598
}
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(
610610
"Encountered anon const with inference variable args but no error reported",
611611
);
612-
}
612+
}
613613

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);
620620

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)
631622
}
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+
}
632633

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+
}
637639
};
638640

639641
let uv = ty::UnevaluatedConst::new(uv.def, args);

0 commit comments

Comments
 (0)