Skip to content

Commit

Permalink
Rollup merge of #100590 - TaKO8Ki:suggest-adding-array-length, r=comp…
Browse files Browse the repository at this point in the history
…iler-errors

Suggest adding an array length if possible

fixes #100448
  • Loading branch information
matthiaskrgr authored Aug 16, 2022
2 parents fc735b0 + 12e609b commit 76dd166
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 26 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{struct_span_err, Applicability, Handler};
use rustc_errors::{struct_span_err, Applicability, Handler, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
Expand Down Expand Up @@ -2235,7 +2235,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
c.value.span,
"using `_` for array lengths is unstable",
)
.emit();
.stash(c.value.span, StashKey::UnderscoreForArrayLengths);
hir::ArrayLen::Body(self.lower_anon_const(c))
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ struct HandlerInner {
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum StashKey {
ItemNoType,
UnderscoreForArrayLengths,
}

fn default_track_diagnostic(_: &Diagnostic) {}
Expand Down
41 changes: 38 additions & 3 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
ErrorGuaranteed,
ErrorGuaranteed, StashKey,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
Expand Down Expand Up @@ -1307,7 +1307,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: expr.span,
})
};
self.tcx.mk_array(element_ty, args.len() as u64)
let array_len = args.len() as u64;
self.suggest_array_len(expr, array_len);
self.tcx.mk_array(element_ty, array_len)
}

fn suggest_array_len(&self, expr: &'tcx hir::Expr<'tcx>, array_len: u64) {
if let Some(parent_hir_id) = self.tcx.hir().find_parent_node(expr.hir_id) {
let ty = match self.tcx.hir().find(parent_hir_id) {
Some(
hir::Node::Local(hir::Local { ty: Some(ty), .. })
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. }),
) => Some(ty),
_ => None,
};
if let Some(ty) = ty
&& let hir::TyKind::Array(_, length) = ty.kind
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
&& let Some(span) = self.tcx.hir().opt_span(hir_id)
{
match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
Some(mut err) => {
err.span_suggestion(
span,
"consider specifying the array length",
array_len,
Applicability::MaybeIncorrect,
);
err.emit();
}
None => ()
}
}
}
}

fn check_expr_const_block(
Expand All @@ -1333,10 +1365,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
element: &'tcx hir::Expr<'tcx>,
count: &'tcx hir::ArrayLen,
expected: Expectation<'tcx>,
_expr: &'tcx hir::Expr<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let count = self.array_length_to_const(count);
if let Some(count) = count.try_eval_usize(tcx, self.param_env) {
self.suggest_array_len(expr, count);
}

let uty = match expected {
ExpectHasType(uty) => match *uty.kind() {
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/array-slice-vec/suggest-array-length.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// run-rustfix
#![allow(unused_variables, dead_code, non_upper_case_globals)]

fn main() {
const Foo: [i32; 3] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let foo: [i32; 3] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let bar: [i32; 3] = [0; 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
}
14 changes: 14 additions & 0 deletions src/test/ui/array-slice-vec/suggest-array-length.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// run-rustfix
#![allow(unused_variables, dead_code, non_upper_case_globals)]

fn main() {
const Foo: [i32; _] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let foo: [i32; _] = [1, 2, 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
let bar: [i32; _] = [0; 3];
//~^ ERROR in expressions, `_` can only be used on the left-hand side of an assignment
//~| ERROR using `_` for array lengths is unstable
}
48 changes: 48 additions & 0 deletions src/test/ui/array-slice-vec/suggest-array-length.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:8:20
|
LL | let foo: [i32; _] = [1, 2, 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:11:20
|
LL | let bar: [i32; _] = [0; 3];
| ^ `_` not allowed here

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/suggest-array-length.rs:5:22
|
LL | const Foo: [i32; _] = [1, 2, 3];
| ^ `_` not allowed here

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:5:22
|
LL | const Foo: [i32; _] = [1, 2, 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:8:20
|
LL | let foo: [i32; _] = [1, 2, 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/suggest-array-length.rs:11:20
|
LL | let bar: [i32; _] = [0; 3];
| ^ help: consider specifying the array length: `3`
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0658`.
12 changes: 6 additions & 6 deletions src/test/ui/async-await/issues/issue-95307.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ LL | async fn new() -> [u8; _];
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/issue-95307.rs:7:28
|
LL | async fn new() -> [u8; _];
| ^ `_` not allowed here

error[E0658]: using `_` for array lengths is unstable
--> $DIR/issue-95307.rs:7:28
|
Expand All @@ -18,12 +24,6 @@ LL | async fn new() -> [u8; _];
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error: in expressions, `_` can only be used on the left-hand side of an assignment
--> $DIR/issue-95307.rs:7:28
|
LL | async fn new() -> [u8; _];
| ^ `_` not allowed here

error: aborting due to 3 previous errors

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

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

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

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

error[E0747]: type provided when a constant was expected
--> $DIR/feature-gate-generic_arg_infer.rs:20:20
|
Expand All @@ -37,6 +28,15 @@ LL | let _x = foo::<_>([1,2]);
= help: const arguments cannot yet be inferred with `_`
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error[E0658]: using `_` for array lengths is unstable
--> $DIR/feature-gate-generic_arg_infer.rs:11:27
|
LL | let _x: [u8; 3] = [0; _];
| ^
|
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0658, E0747.
Expand Down

0 comments on commit 76dd166

Please sign in to comment.