Skip to content

Commit bb229b8

Browse files
authored
Rollup merge of #80012 - sasurau4:feature/point-constant-identifier-E0435, r=petrochenkov
Add pointing const identifier when emitting E0435 Fix #79919
2 parents b5c496d + c71348a commit bb229b8

16 files changed

+116
-28
lines changed

compiler/rustc_error_codes/src/error_codes/E0435.md

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ let foo = 42;
77
let a: [u8; foo]; // error: attempt to use a non-constant value in a constant
88
```
99

10+
'constant' means 'a compile-time value'.
11+
12+
More details can be found in the [Variables and Mutability] section of the book.
13+
14+
[Variables and Mutability]: https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
15+
1016
To fix this error, please replace the value with a constant. Example:
1117

1218
```

compiler/rustc_resolve/src/diagnostics.rs

+7-1
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

+28-10
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

+32-8
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.
@@ -1837,14 +1837,16 @@ impl<'a> Resolver<'a> {
18371837
// Use the rib kind to determine whether we are resolving parameters
18381838
// (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
18391839
let rib_ident = if ribs[i].kind.contains_params() { normalized_ident } else { ident };
1840-
if let Some(res) = ribs[i].bindings.get(&rib_ident).cloned() {
1840+
if let Some((original_rib_ident_def, res)) = ribs[i].bindings.get_key_value(&rib_ident)
1841+
{
18411842
// The ident resolves to a type parameter or local variable.
18421843
return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
18431844
i,
18441845
rib_ident,
1845-
res,
1846+
*res,
18461847
record_used,
18471848
path_span,
1849+
*original_rib_ident_def,
18481850
ribs,
18491851
)));
18501852
}
@@ -2556,6 +2558,7 @@ impl<'a> Resolver<'a> {
25562558
mut res: Res,
25572559
record_used: bool,
25582560
span: Span,
2561+
original_rib_ident_def: Ident,
25592562
all_ribs: &[Rib<'a>],
25602563
) -> Res {
25612564
const CG_BUG_STR: &str = "min_const_generics resolve check didn't stop compilation";
@@ -2602,10 +2605,31 @@ impl<'a> Resolver<'a> {
26022605
res_err = Some(CannotCaptureDynamicEnvironmentInFnItem);
26032606
}
26042607
}
2605-
ConstantItemRibKind(_) => {
2608+
ConstantItemRibKind(_, item) => {
26062609
// Still doesn't deal with upvars
26072610
if record_used {
2608-
self.report_error(span, AttemptToUseNonConstantValueInConstant);
2611+
let (span, resolution_error) =
2612+
if let Some((ident, constant_item_kind)) = item {
2613+
let kind_str = match constant_item_kind {
2614+
ConstantItemKind::Const => "const",
2615+
ConstantItemKind::Static => "static",
2616+
};
2617+
let sugg = format!(
2618+
"consider using `let` instead of `{}`",
2619+
kind_str
2620+
);
2621+
(span, AttemptToUseNonConstantValueInConstant(ident, sugg))
2622+
} else {
2623+
let sugg = "consider using `const` instead of `let`";
2624+
(
2625+
rib_ident.span,
2626+
AttemptToUseNonConstantValueInConstant(
2627+
original_rib_ident_def,
2628+
sugg.to_string(),
2629+
),
2630+
)
2631+
};
2632+
self.report_error(span, resolution_error);
26092633
}
26102634
return Res::Err;
26112635
}
@@ -2641,7 +2665,7 @@ impl<'a> Resolver<'a> {
26412665
in_ty_param_default = true;
26422666
continue;
26432667
}
2644-
ConstantItemRibKind(trivial) => {
2668+
ConstantItemRibKind(trivial, _) => {
26452669
let features = self.session.features_untracked();
26462670
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
26472671
if !(trivial
@@ -2734,7 +2758,7 @@ impl<'a> Resolver<'a> {
27342758
in_ty_param_default = true;
27352759
continue;
27362760
}
2737-
ConstantItemRibKind(trivial) => {
2761+
ConstantItemRibKind(trivial, _) => {
27382762
let features = self.session.features_untracked();
27392763
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
27402764
if !(trivial

src/test/ui/error-codes/E0435.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/E0435.rs:3:17
33
|
4+
LL | let foo = 42u32;
5+
| --- help: consider using `const` instead of `let`
46
LL | let _: [u8; foo];
57
| ^^^ non-constant value
68

src/test/ui/impl-trait/bindings.stderr

+12-4
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,33 @@ error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/bindings.rs:5:29
33
|
44
LL | const foo: impl Clone = x;
5-
| ^ non-constant value
5+
| --- ^ non-constant value
6+
| |
7+
| help: consider using `let` instead of `const`
68

79
error[E0435]: attempt to use a non-constant value in a constant
810
--> $DIR/bindings.rs:11:33
911
|
1012
LL | const foo: impl Clone = x;
11-
| ^ non-constant value
13+
| --- ^ non-constant value
14+
| |
15+
| help: consider using `let` instead of `const`
1216

1317
error[E0435]: attempt to use a non-constant value in a constant
1418
--> $DIR/bindings.rs:18:33
1519
|
1620
LL | const foo: impl Clone = x;
17-
| ^ non-constant value
21+
| --- ^ non-constant value
22+
| |
23+
| help: consider using `let` instead of `const`
1824

1925
error[E0435]: attempt to use a non-constant value in a constant
2026
--> $DIR/bindings.rs:25:33
2127
|
2228
LL | const foo: impl Clone = x;
23-
| ^ non-constant value
29+
| --- ^ non-constant value
30+
| |
31+
| help: consider using `let` instead of `const`
2432

2533
warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
2634
--> $DIR/bindings.rs:1:12

src/test/ui/issues/issue-27433.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-27433.rs:3:23
33
|
44
LL | const FOO : u32 = foo;
5-
| ^^^ non-constant value
5+
| --- ^^^ non-constant value
6+
| |
7+
| help: consider using `let` instead of `const`
68

79
error: aborting due to previous error
810

src/test/ui/issues/issue-3521-2.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-3521-2.rs:4:23
33
|
44
LL | static y: isize = foo + 1;
5-
| ^^^ non-constant value
5+
| - ^^^ non-constant value
6+
| |
7+
| help: consider using `let` instead of `static`
68

79
error: aborting due to previous error
810

src/test/ui/issues/issue-3521.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-3521.rs:6:15
33
|
4+
LL | let foo = 100;
5+
| --- help: consider using `const` instead of `let`
6+
...
47
LL | Bar = foo
58
| ^^^ non-constant value
69

src/test/ui/issues/issue-3668-2.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-3668-2.rs:2:27
33
|
44
LL | static child: isize = x + 1;
5-
| ^ non-constant value
5+
| ----- ^ non-constant value
6+
| |
7+
| help: consider using `let` instead of `static`
68

79
error: aborting due to previous error
810

src/test/ui/issues/issue-3668.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-3668.rs:8:34
33
|
44
LL | static childVal: Box<P> = self.child.get();
5-
| ^^^^ non-constant value
5+
| -------- ^^^^ non-constant value
6+
| |
7+
| help: consider using `let` instead of `static`
68

79
error: aborting due to previous error
810

src/test/ui/issues/issue-42060.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-42060.rs:3:23
33
|
4+
LL | let thing = ();
5+
| ----- help: consider using `const` instead of `let`
46
LL | let other: typeof(thing) = thing;
57
| ^^^^^ non-constant value
68

79
error[E0435]: attempt to use a non-constant value in a constant
810
--> $DIR/issue-42060.rs:9:13
911
|
12+
LL | let q = 1;
13+
| - help: consider using `const` instead of `let`
1014
LL | <typeof(q)>::N
1115
| ^ non-constant value
1216

src/test/ui/issues/issue-44239.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/issue-44239.rs:6:26
33
|
4+
LL | let n = 0;
5+
| - help: consider using `const` instead of `let`
6+
...
47
LL | const N: usize = n;
58
| ^ non-constant value
69

src/test/ui/non-constant-expr-for-arr-len.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/non-constant-expr-for-arr-len.rs:5:22
33
|
4+
LL | fn bar(n: usize) {
5+
| - help: consider using `const` instead of `let`
46
LL | let _x = [0; n];
57
| ^ non-constant value
68

src/test/ui/repeat_count.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
error[E0435]: attempt to use a non-constant value in a constant
22
--> $DIR/repeat_count.rs:5:17
33
|
4+
LL | let n = 1;
5+
| - help: consider using `const` instead of `let`
46
LL | let a = [0; n];
57
| ^ non-constant value
68

0 commit comments

Comments
 (0)