Skip to content

Commit 76dd166

Browse files
authored
Rollup merge of #100590 - TaKO8Ki:suggest-adding-array-length, r=compiler-errors
Suggest adding an array length if possible fixes #100448
2 parents fc735b0 + 12e609b commit 76dd166

File tree

8 files changed

+138
-26
lines changed

8 files changed

+138
-26
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use rustc_data_structures::fx::FxHashMap;
4848
use rustc_data_structures::sorted_map::SortedMap;
4949
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5050
use rustc_data_structures::sync::Lrc;
51-
use rustc_errors::{struct_span_err, Applicability, Handler};
51+
use rustc_errors::{struct_span_err, Applicability, Handler, StashKey};
5252
use rustc_hir as hir;
5353
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5454
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
@@ -2235,7 +2235,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22352235
c.value.span,
22362236
"using `_` for array lengths is unstable",
22372237
)
2238-
.emit();
2238+
.stash(c.value.span, StashKey::UnderscoreForArrayLengths);
22392239
hir::ArrayLen::Body(self.lower_anon_const(c))
22402240
}
22412241
}

compiler/rustc_errors/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ struct HandlerInner {
457457
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
458458
pub enum StashKey {
459459
ItemNoType,
460+
UnderscoreForArrayLengths,
460461
}
461462

462463
fn default_track_diagnostic(_: &Diagnostic) {}

compiler/rustc_typeck/src/check/expr.rs

+38-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_data_structures::fx::FxHashMap;
2828
use rustc_data_structures::stack::ensure_sufficient_stack;
2929
use rustc_errors::{
3030
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
31-
ErrorGuaranteed,
31+
ErrorGuaranteed, StashKey,
3232
};
3333
use rustc_hir as hir;
3434
use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -1307,7 +1307,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13071307
span: expr.span,
13081308
})
13091309
};
1310-
self.tcx.mk_array(element_ty, args.len() as u64)
1310+
let array_len = args.len() as u64;
1311+
self.suggest_array_len(expr, array_len);
1312+
self.tcx.mk_array(element_ty, array_len)
1313+
}
1314+
1315+
fn suggest_array_len(&self, expr: &'tcx hir::Expr<'tcx>, array_len: u64) {
1316+
if let Some(parent_hir_id) = self.tcx.hir().find_parent_node(expr.hir_id) {
1317+
let ty = match self.tcx.hir().find(parent_hir_id) {
1318+
Some(
1319+
hir::Node::Local(hir::Local { ty: Some(ty), .. })
1320+
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. }),
1321+
) => Some(ty),
1322+
_ => None,
1323+
};
1324+
if let Some(ty) = ty
1325+
&& let hir::TyKind::Array(_, length) = ty.kind
1326+
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
1327+
&& let Some(span) = self.tcx.hir().opt_span(hir_id)
1328+
{
1329+
match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
1330+
Some(mut err) => {
1331+
err.span_suggestion(
1332+
span,
1333+
"consider specifying the array length",
1334+
array_len,
1335+
Applicability::MaybeIncorrect,
1336+
);
1337+
err.emit();
1338+
}
1339+
None => ()
1340+
}
1341+
}
1342+
}
13111343
}
13121344

13131345
fn check_expr_const_block(
@@ -1333,10 +1365,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13331365
element: &'tcx hir::Expr<'tcx>,
13341366
count: &'tcx hir::ArrayLen,
13351367
expected: Expectation<'tcx>,
1336-
_expr: &'tcx hir::Expr<'tcx>,
1368+
expr: &'tcx hir::Expr<'tcx>,
13371369
) -> Ty<'tcx> {
13381370
let tcx = self.tcx;
13391371
let count = self.array_length_to_const(count);
1372+
if let Some(count) = count.try_eval_usize(tcx, self.param_env) {
1373+
self.suggest_array_len(expr, count);
1374+
}
13401375

13411376
let uty = match expected {
13421377
ExpectHasType(uty) => match *uty.kind() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// run-rustfix
2+
#![allow(unused_variables, dead_code, non_upper_case_globals)]
3+
4+
fn main() {
5+
const Foo: [i32; 3] = [1, 2, 3];
6+
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
7+
//~| ERROR using `_` for array lengths is unstable
8+
let foo: [i32; 3] = [1, 2, 3];
9+
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
10+
//~| ERROR using `_` for array lengths is unstable
11+
let bar: [i32; 3] = [0; 3];
12+
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
13+
//~| ERROR using `_` for array lengths is unstable
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// run-rustfix
2+
#![allow(unused_variables, dead_code, non_upper_case_globals)]
3+
4+
fn main() {
5+
const Foo: [i32; _] = [1, 2, 3];
6+
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
7+
//~| ERROR using `_` for array lengths is unstable
8+
let foo: [i32; _] = [1, 2, 3];
9+
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
10+
//~| ERROR using `_` for array lengths is unstable
11+
let bar: [i32; _] = [0; 3];
12+
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
13+
//~| ERROR using `_` for array lengths is unstable
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
error: in expressions, `_` can only be used on the left-hand side of an assignment
2+
--> $DIR/suggest-array-length.rs:8:20
3+
|
4+
LL | let foo: [i32; _] = [1, 2, 3];
5+
| ^ `_` not allowed here
6+
7+
error: in expressions, `_` can only be used on the left-hand side of an assignment
8+
--> $DIR/suggest-array-length.rs:11:20
9+
|
10+
LL | let bar: [i32; _] = [0; 3];
11+
| ^ `_` not allowed here
12+
13+
error: in expressions, `_` can only be used on the left-hand side of an assignment
14+
--> $DIR/suggest-array-length.rs:5:22
15+
|
16+
LL | const Foo: [i32; _] = [1, 2, 3];
17+
| ^ `_` not allowed here
18+
19+
error[E0658]: using `_` for array lengths is unstable
20+
--> $DIR/suggest-array-length.rs:5:22
21+
|
22+
LL | const Foo: [i32; _] = [1, 2, 3];
23+
| ^ help: consider specifying the array length: `3`
24+
|
25+
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
26+
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
27+
28+
error[E0658]: using `_` for array lengths is unstable
29+
--> $DIR/suggest-array-length.rs:8:20
30+
|
31+
LL | let foo: [i32; _] = [1, 2, 3];
32+
| ^ help: consider specifying the array length: `3`
33+
|
34+
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
35+
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
36+
37+
error[E0658]: using `_` for array lengths is unstable
38+
--> $DIR/suggest-array-length.rs:11:20
39+
|
40+
LL | let bar: [i32; _] = [0; 3];
41+
| ^ help: consider specifying the array length: `3`
42+
|
43+
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
44+
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
45+
46+
error: aborting due to 6 previous errors
47+
48+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/async-await/issues/issue-95307.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ LL | async fn new() -> [u8; _];
99
= note: `async` trait functions are not currently supported
1010
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
1111

12+
error: in expressions, `_` can only be used on the left-hand side of an assignment
13+
--> $DIR/issue-95307.rs:7:28
14+
|
15+
LL | async fn new() -> [u8; _];
16+
| ^ `_` not allowed here
17+
1218
error[E0658]: using `_` for array lengths is unstable
1319
--> $DIR/issue-95307.rs:7:28
1420
|
@@ -18,12 +24,6 @@ LL | async fn new() -> [u8; _];
1824
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
1925
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
2026

21-
error: in expressions, `_` can only be used on the left-hand side of an assignment
22-
--> $DIR/issue-95307.rs:7:28
23-
|
24-
LL | async fn new() -> [u8; _];
25-
| ^ `_` not allowed here
26-
2727
error: aborting due to 3 previous errors
2828

2929
Some errors have detailed explanations: E0658, E0706.

src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
1-
error[E0658]: using `_` for array lengths is unstable
1+
error: in expressions, `_` can only be used on the left-hand side of an assignment
22
--> $DIR/feature-gate-generic_arg_infer.rs:11:27
33
|
44
LL | let _x: [u8; 3] = [0; _];
5-
| ^
6-
|
7-
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
8-
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
5+
| ^ `_` not allowed here
96

107
error: in expressions, `_` can only be used on the left-hand side of an assignment
11-
--> $DIR/feature-gate-generic_arg_infer.rs:11:27
8+
--> $DIR/feature-gate-generic_arg_infer.rs:14:18
129
|
13-
LL | let _x: [u8; 3] = [0; _];
14-
| ^ `_` not allowed here
10+
LL | let _y: [u8; _] = [0; 3];
11+
| ^ `_` not allowed here
1512

1613
error[E0658]: using `_` for array lengths is unstable
1714
--> $DIR/feature-gate-generic_arg_infer.rs:14:18
1815
|
1916
LL | let _y: [u8; _] = [0; 3];
20-
| ^
17+
| ^ help: consider specifying the array length: `3`
2118
|
2219
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
2320
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
2421

25-
error: in expressions, `_` can only be used on the left-hand side of an assignment
26-
--> $DIR/feature-gate-generic_arg_infer.rs:14:18
27-
|
28-
LL | let _y: [u8; _] = [0; 3];
29-
| ^ `_` not allowed here
30-
3122
error[E0747]: type provided when a constant was expected
3223
--> $DIR/feature-gate-generic_arg_infer.rs:20:20
3324
|
@@ -37,6 +28,15 @@ LL | let _x = foo::<_>([1,2]);
3728
= help: const arguments cannot yet be inferred with `_`
3829
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
3930

31+
error[E0658]: using `_` for array lengths is unstable
32+
--> $DIR/feature-gate-generic_arg_infer.rs:11:27
33+
|
34+
LL | let _x: [u8; 3] = [0; _];
35+
| ^
36+
|
37+
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
38+
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
39+
4040
error: aborting due to 5 previous errors
4141

4242
Some errors have detailed explanations: E0658, E0747.

0 commit comments

Comments
 (0)