diff options
| author | Boxy <rust@boxyuwu.dev> | 2025-05-01 16:22:31 +0100 | 
|---|---|---|
| committer | Boxy <rust@boxyuwu.dev> | 2025-05-22 12:47:19 +0100 | 
| commit | 217c4ad427a5dbf6b23f23c70358a31064884231 (patch) | |
| tree | d3a8c985eb24510dbd38835f723627cd3734f948 /compiler/rustc_trait_selection/src/traits/mod.rs | |
| parent | b1774b8d7382325d2bb5cc518e463ae9d6de5898 (diff) | |
| download | rust-217c4ad427a5dbf6b23f23c70358a31064884231.tar.gz rust-217c4ad427a5dbf6b23f23c70358a31064884231.zip | |
Review Comments
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/mod.rs')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/mod.rs | 138 | 
1 files changed, 69 insertions, 69 deletions
| diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index c174de44558..d8e83dc72b0 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -542,6 +542,9 @@ pub fn try_evaluate_const<'tcx>( | ty::ConstKind::Placeholder(_) | ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers), ty::ConstKind::Unevaluated(uv) => { + let opt_anon_const_kind = + (tcx.def_kind(uv.def) == DefKind::AnonConst).then(|| tcx.anon_const_kind(uv.def)); + // Postpone evaluation of constants that depend on generic parameters or // inference variables. // @@ -553,87 +556,84 @@ pub fn try_evaluate_const<'tcx>( // // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself // instead of having this logic here - let (args, typing_env) = if tcx.def_kind(uv.def) == DefKind::AnonConst - && let ty::AnonConstKind::GCEConst = tcx.anon_const_kind(uv.def) - { + let (args, typing_env) = match opt_anon_const_kind { // We handle `generic_const_exprs` separately as reasonable ways of handling constants in the type system // completely fall apart under `generic_const_exprs` and makes this whole function Really hard to reason // about if you have to consider gce whatsoever. - - if uv.has_non_region_infer() || uv.has_non_region_param() { - // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause - // inference variables and generic parameters to show up in `ty::Const` even though the anon const - // does not actually make use of them. We handle this case specially and attempt to evaluate anyway. - match tcx.thir_abstract_const(uv.def) { - Ok(Some(ct)) => { - let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, uv.args)); - if let Err(e) = ct.error_reported() { - return Err(EvaluateConstErr::EvaluationFailure(e)); - } else if ct.has_non_region_infer() || ct.has_non_region_param() { - // If the anon const *does* actually use generic parameters or inference variables from - // the generic arguments provided for it, then we should *not* attempt to evaluate it. - return Err(EvaluateConstErr::HasGenericsOrInfers); - } else { - let args = - replace_param_and_infer_args_with_placeholder(tcx, uv.args); - let typing_env = infcx - .typing_env(tcx.erase_regions(param_env)) - .with_post_analysis_normalized(tcx); + Some(ty::AnonConstKind::GCE) => { + if uv.has_non_region_infer() || uv.has_non_region_param() { + // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause + // inference variables and generic parameters to show up in `ty::Const` even though the anon const + // does not actually make use of them. We handle this case specially and attempt to evaluate anyway. + match tcx.thir_abstract_const(uv.def) { + Ok(Some(ct)) => { + let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, uv.args)); + if let Err(e) = ct.error_reported() { + return Err(EvaluateConstErr::EvaluationFailure(e)); + } else if ct.has_non_region_infer() || ct.has_non_region_param() { + // If the anon const *does* actually use generic parameters or inference variables from + // the generic arguments provided for it, then we should *not* attempt to evaluate it. + return Err(EvaluateConstErr::HasGenericsOrInfers); + } else { + let args = + replace_param_and_infer_args_with_placeholder(tcx, uv.args); + let typing_env = infcx + .typing_env(tcx.erase_regions(param_env)) + .with_post_analysis_normalized(tcx); + (args, typing_env) + } + } + Err(_) | Ok(None) => { + let args = GenericArgs::identity_for_item(tcx, uv.def); + let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def); (args, typing_env) } } - Err(_) | Ok(None) => { - let args = GenericArgs::identity_for_item(tcx, uv.def); - let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def); - (args, typing_env) - } + } else { + let typing_env = infcx + .typing_env(tcx.erase_regions(param_env)) + .with_post_analysis_normalized(tcx); + (uv.args, typing_env) } - } else { - let typing_env = infcx - .typing_env(tcx.erase_regions(param_env)) - .with_post_analysis_normalized(tcx); - (uv.args, typing_env) - } - } else if tcx.def_kind(uv.def) == DefKind::AnonConst - && let ty::AnonConstKind::RepeatExprCount = tcx.anon_const_kind(uv.def) - { - if uv.has_non_region_infer() { - // Diagnostics will sometimes replace the identity args of anon consts in - // array repeat expr counts with inference variables so we have to handle this - // even though it is not something we should ever actually encounter. - // - // Array repeat expr counts are allowed to syntactically use generic parameters - // but must not actually depend on them in order to evalaute successfully. This means - // that it is actually fine to evalaute them in their own environment rather than with - // the actually provided generic arguments. - tcx.dcx().delayed_bug( - "Encountered anon const with inference variable args but no error reported", - ); } + Some(ty::AnonConstKind::RepeatExprCount) => { + if uv.has_non_region_infer() { + // Diagnostics will sometimes replace the identity args of anon consts in + // array repeat expr counts with inference variables so we have to handle this + // even though it is not something we should ever actually encounter. + // + // Array repeat expr counts are allowed to syntactically use generic parameters + // but must not actually depend on them in order to evalaute successfully. This means + // that it is actually fine to evalaute them in their own environment rather than with + // the actually provided generic arguments. + tcx.dcx().delayed_bug("AnonConst with infer args but no error reported"); + } - // The generic args of repeat expr counts under `min_const_generics` are not supposed to - // affect evaluation of the constant as this would make it a "truly" generic const arg. - // To prevent this we discard all the generic arguments and evalaute with identity args - // and in its own environment instead of the current environment we are normalizing in. - let args = GenericArgs::identity_for_item(tcx, uv.def); - let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def); + // The generic args of repeat expr counts under `min_const_generics` are not supposed to + // affect evaluation of the constant as this would make it a "truly" generic const arg. + // To prevent this we discard all the generic arguments and evalaute with identity args + // and in its own environment instead of the current environment we are normalizing in. + let args = GenericArgs::identity_for_item(tcx, uv.def); + let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def); - (args, typing_env) - } else { - // We are only dealing with "truly" generic/uninferred constants here: - // - GCEConsts have been handled separately - // - Repeat expr count back compat consts have also been handled separately - // So we are free to simply defer evaluation here. - // - // FIXME: This assumes that `args` are normalized which is not necessarily true - if uv.args.has_non_region_param() || uv.args.has_non_region_infer() { - return Err(EvaluateConstErr::HasGenericsOrInfers); + (args, typing_env) } + _ => { + // We are only dealing with "truly" generic/uninferred constants here: + // - GCEConsts have been handled separately + // - Repeat expr count back compat consts have also been handled separately + // So we are free to simply defer evaluation here. + // + // FIXME: This assumes that `args` are normalized which is not necessarily true + if uv.args.has_non_region_param() || uv.args.has_non_region_infer() { + return Err(EvaluateConstErr::HasGenericsOrInfers); + } - let typing_env = infcx - .typing_env(tcx.erase_regions(param_env)) - .with_post_analysis_normalized(tcx); - (uv.args, typing_env) + let typing_env = infcx + .typing_env(tcx.erase_regions(param_env)) + .with_post_analysis_normalized(tcx); + (uv.args, typing_env) + } }; let uv = ty::UnevaluatedConst::new(uv.def, args); | 
