Skip to content

Commit f03907b

Browse files
committed
Add pointing const identifier when emitting E0435
1 parent 68ec332 commit f03907b

File tree

3 files changed

+67
-19
lines changed

3 files changed

+67
-19
lines changed

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,13 +398,19 @@ impl<'a> Resolver<'a> {
398398
err.help("use the `|| { ... }` closure form instead");
399399
err
400400
}
401-
ResolutionError::AttemptToUseNonConstantValueInConstant => {
401+
ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg) => {
402402
let mut err = struct_span_err!(
403403
self.session,
404404
span,
405405
E0435,
406406
"attempt to use a non-constant value in a constant"
407407
);
408+
err.span_suggestion(
409+
ident.span,
410+
&sugg,
411+
"".to_string(),
412+
Applicability::MaybeIncorrect,
413+
);
408414
err.span_label(span, "non-constant value");
409415
err
410416
}

compiler/rustc_resolve/src/late.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ crate enum HasGenericParams {
9292
No,
9393
}
9494

95+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
96+
crate enum ConstantItemKind {
97+
Const,
98+
Static,
99+
}
100+
95101
/// The rib kind restricts certain accesses,
96102
/// e.g. to a `Res::Local` of an outer item.
97103
#[derive(Copy, Clone, Debug)]
@@ -119,7 +125,7 @@ crate enum RibKind<'a> {
119125
///
120126
/// The `bool` indicates if this constant may reference generic parameters
121127
/// and is used to only allow generic parameters to be used in trivial constant expressions.
122-
ConstantItemRibKind(bool),
128+
ConstantItemRibKind(bool, Option<(Ident, ConstantItemKind)>),
123129

124130
/// We passed through a module.
125131
ModuleRibKind(Module<'a>),
@@ -145,7 +151,7 @@ impl RibKind<'_> {
145151
NormalRibKind
146152
| ClosureOrAsyncRibKind
147153
| FnItemRibKind
148-
| ConstantItemRibKind(_)
154+
| ConstantItemRibKind(..)
149155
| ModuleRibKind(_)
150156
| MacroDefinition(_)
151157
| ConstParamTyRibKind => false,
@@ -634,7 +640,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
634640
// Note that we might not be inside of an repeat expression here,
635641
// but considering that `IsRepeatExpr` is only relevant for
636642
// non-trivial constants this is doesn't matter.
637-
self.with_constant_rib(IsRepeatExpr::No, true, |this| {
643+
self.with_constant_rib(IsRepeatExpr::No, true, None, |this| {
638644
this.smart_resolve_path(
639645
ty.id,
640646
qself.as_ref(),
@@ -843,7 +849,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
843849
| ClosureOrAsyncRibKind
844850
| FnItemRibKind
845851
| ItemRibKind(..)
846-
| ConstantItemRibKind(_)
852+
| ConstantItemRibKind(..)
847853
| ModuleRibKind(..)
848854
| ForwardTyParamBanRibKind
849855
| ConstParamTyRibKind => {
@@ -970,6 +976,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
970976
this.with_constant_rib(
971977
IsRepeatExpr::No,
972978
true,
979+
None,
973980
|this| this.visit_expr(expr),
974981
);
975982
}
@@ -1012,11 +1019,19 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
10121019
self.with_item_rib(HasGenericParams::No, |this| {
10131020
this.visit_ty(ty);
10141021
if let Some(expr) = expr {
1022+
let constant_item_kind = match item.kind {
1023+
ItemKind::Const(..) => ConstantItemKind::Const,
1024+
ItemKind::Static(..) => ConstantItemKind::Static,
1025+
_ => unreachable!(),
1026+
};
10151027
// We already forbid generic params because of the above item rib,
10161028
// so it doesn't matter whether this is a trivial constant.
1017-
this.with_constant_rib(IsRepeatExpr::No, true, |this| {
1018-
this.visit_expr(expr)
1019-
});
1029+
this.with_constant_rib(
1030+
IsRepeatExpr::No,
1031+
true,
1032+
Some((item.ident, constant_item_kind)),
1033+
|this| this.visit_expr(expr),
1034+
);
10201035
}
10211036
});
10221037
}
@@ -1118,15 +1133,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
11181133
&mut self,
11191134
is_repeat: IsRepeatExpr,
11201135
is_trivial: bool,
1136+
item: Option<(Ident, ConstantItemKind)>,
11211137
f: impl FnOnce(&mut Self),
11221138
) {
11231139
debug!("with_constant_rib: is_repeat={:?} is_trivial={}", is_repeat, is_trivial);
1124-
self.with_rib(ValueNS, ConstantItemRibKind(is_trivial), |this| {
1140+
self.with_rib(ValueNS, ConstantItemRibKind(is_trivial, item), |this| {
11251141
this.with_rib(
11261142
TypeNS,
1127-
ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial),
1143+
ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial, item),
11281144
|this| {
1129-
this.with_label_rib(ConstantItemRibKind(is_trivial), f);
1145+
this.with_label_rib(ConstantItemRibKind(is_trivial, item), f);
11301146
},
11311147
)
11321148
});
@@ -1266,6 +1282,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
12661282
this.with_constant_rib(
12671283
IsRepeatExpr::No,
12681284
true,
1285+
None,
12691286
|this| {
12701287
visit::walk_assoc_item(
12711288
this,
@@ -2200,6 +2217,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
22002217
self.with_constant_rib(
22012218
is_repeat,
22022219
constant.value.is_potential_trivial_const_param(),
2220+
None,
22032221
|this| {
22042222
visit::walk_anon_const(this, constant);
22052223
},

compiler/rustc_resolve/src/lib.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use tracing::debug;
6464
use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding};
6565
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
6666
use imports::{Import, ImportKind, ImportResolver, NameResolution};
67-
use late::{HasGenericParams, PathSource, Rib, RibKind::*};
67+
use late::{ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind::*};
6868
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
6969

7070
type Res = def::Res<NodeId>;
@@ -210,7 +210,7 @@ enum ResolutionError<'a> {
210210
/// Error E0434: can't capture dynamic environment in a fn item.
211211
CannotCaptureDynamicEnvironmentInFnItem,
212212
/// Error E0435: attempt to use a non-constant value in a constant.
213-
AttemptToUseNonConstantValueInConstant,
213+
AttemptToUseNonConstantValueInConstant(Ident, String),
214214
/// Error E0530: `X` bindings cannot shadow `Y`s.
215215
BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
216216
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
@@ -1821,14 +1821,16 @@ impl<'a> Resolver<'a> {
18211821
// Use the rib kind to determine whether we are resolving parameters
18221822
// (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
18231823
let rib_ident = if ribs[i].kind.contains_params() { normalized_ident } else { ident };
1824-
if let Some(res) = ribs[i].bindings.get(&rib_ident).cloned() {
1824+
if let Some((original_rib_ident_def, res)) = ribs[i].bindings.get_key_value(&rib_ident)
1825+
{
18251826
// The ident resolves to a type parameter or local variable.
18261827
return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
18271828
i,
18281829
rib_ident,
1829-
res,
1830+
*res,
18301831
record_used,
18311832
path_span,
1833+
*original_rib_ident_def,
18321834
ribs,
18331835
)));
18341836
}
@@ -2540,6 +2542,7 @@ impl<'a> Resolver<'a> {
25402542
mut res: Res,
25412543
record_used: bool,
25422544
span: Span,
2545+
original_rib_ident_def: Ident,
25432546
all_ribs: &[Rib<'a>],
25442547
) -> Res {
25452548
const CG_BUG_STR: &str = "min_const_generics resolve check didn't stop compilation";
@@ -2586,10 +2589,31 @@ impl<'a> Resolver<'a> {
25862589
res_err = Some(CannotCaptureDynamicEnvironmentInFnItem);
25872590
}
25882591
}
2589-
ConstantItemRibKind(_) => {
2592+
ConstantItemRibKind(_, item) => {
25902593
// Still doesn't deal with upvars
25912594
if record_used {
2592-
self.report_error(span, AttemptToUseNonConstantValueInConstant);
2595+
let (span, resolution_error) =
2596+
if let Some((ident, constant_item_kind)) = item {
2597+
let kind_str = match constant_item_kind {
2598+
ConstantItemKind::Const => "const",
2599+
ConstantItemKind::Static => "static",
2600+
};
2601+
let sugg = format!(
2602+
"consider using `let` instead of `{}`",
2603+
kind_str
2604+
);
2605+
(span, AttemptToUseNonConstantValueInConstant(ident, sugg))
2606+
} else {
2607+
let sugg = "consider using `const` instead of `let`";
2608+
(
2609+
rib_ident.span,
2610+
AttemptToUseNonConstantValueInConstant(
2611+
original_rib_ident_def,
2612+
sugg.to_string(),
2613+
),
2614+
)
2615+
};
2616+
self.report_error(span, resolution_error);
25932617
}
25942618
return Res::Err;
25952619
}
@@ -2625,7 +2649,7 @@ impl<'a> Resolver<'a> {
26252649
in_ty_param_default = true;
26262650
continue;
26272651
}
2628-
ConstantItemRibKind(trivial) => {
2652+
ConstantItemRibKind(trivial, _) => {
26292653
let features = self.session.features_untracked();
26302654
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
26312655
if !(trivial
@@ -2718,7 +2742,7 @@ impl<'a> Resolver<'a> {
27182742
in_ty_param_default = true;
27192743
continue;
27202744
}
2721-
ConstantItemRibKind(trivial) => {
2745+
ConstantItemRibKind(trivial, _) => {
27222746
let features = self.session.features_untracked();
27232747
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
27242748
if !(trivial

0 commit comments

Comments
 (0)