suggest adding an array length if possible
This commit is contained in:
parent
0068b8bf4b
commit
4d1b5f0d99
8 changed files with 153 additions and 25 deletions
|
@ -49,7 +49,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sorted_map::SortedMap;
|
use rustc_data_structures::sorted_map::SortedMap;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::Lrc;
|
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 as hir;
|
||||||
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
||||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||||
|
@ -2236,7 +2236,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
c.value.span,
|
c.value.span,
|
||||||
"using `_` for array lengths is unstable",
|
"using `_` for array lengths is unstable",
|
||||||
)
|
)
|
||||||
.emit();
|
.stash(c.value.span, StashKey::UnderscoreForArrayLengths);
|
||||||
hir::ArrayLen::Body(self.lower_anon_const(c))
|
hir::ArrayLen::Body(self.lower_anon_const(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -457,6 +457,7 @@ struct HandlerInner {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
pub enum StashKey {
|
pub enum StashKey {
|
||||||
ItemNoType,
|
ItemNoType,
|
||||||
|
UnderscoreForArrayLengths,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_track_diagnostic(_: &Diagnostic) {}
|
fn default_track_diagnostic(_: &Diagnostic) {}
|
||||||
|
|
|
@ -28,7 +28,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
|
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
|
||||||
ErrorGuaranteed,
|
ErrorGuaranteed, StashKey,
|
||||||
};
|
};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
|
@ -1307,7 +1307,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
span: expr.span,
|
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_verbose(
|
||||||
|
span,
|
||||||
|
"consider adding an array length",
|
||||||
|
array_len,
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
None => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr_const_block(
|
fn check_expr_const_block(
|
||||||
|
@ -1333,10 +1365,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
element: &'tcx hir::Expr<'tcx>,
|
element: &'tcx hir::Expr<'tcx>,
|
||||||
count: &'tcx hir::ArrayLen,
|
count: &'tcx hir::ArrayLen,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
_expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let count = self.array_length_to_const(count);
|
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 {
|
let uty = match expected {
|
||||||
ExpectHasType(uty) => match *uty.kind() {
|
ExpectHasType(uty) => match *uty.kind() {
|
||||||
|
|
14
src/test/ui/array-slice-vec/suggest-array-length.fixed
Normal file
14
src/test/ui/array-slice-vec/suggest-array-length.fixed
Normal file
|
@ -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
src/test/ui/array-slice-vec/suggest-array-length.rs
Normal file
14
src/test/ui/array-slice-vec/suggest-array-length.rs
Normal file
|
@ -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
|
||||||
|
}
|
60
src/test/ui/array-slice-vec/suggest-array-length.stderr
Normal file
60
src/test/ui/array-slice-vec/suggest-array-length.stderr
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
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];
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= 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
|
||||||
|
help: consider adding an array length
|
||||||
|
|
|
||||||
|
LL | const Foo: [i32; 3] = [1, 2, 3];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0658]: using `_` for array lengths is unstable
|
||||||
|
--> $DIR/suggest-array-length.rs:8:20
|
||||||
|
|
|
||||||
|
LL | let foo: [i32; _] = [1, 2, 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
|
||||||
|
help: consider adding an array length
|
||||||
|
|
|
||||||
|
LL | let foo: [i32; 3] = [1, 2, 3];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0658]: using `_` for array lengths is unstable
|
||||||
|
--> $DIR/suggest-array-length.rs:11:20
|
||||||
|
|
|
||||||
|
LL | let bar: [i32; _] = [0; 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
|
||||||
|
help: consider adding an array length
|
||||||
|
|
|
||||||
|
LL | let bar: [i32; 3] = [0; 3];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
|
@ -9,6 +9,12 @@ LL | async fn new() -> [u8; _];
|
||||||
= note: `async` trait functions are not currently supported
|
= note: `async` trait functions are not currently supported
|
||||||
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
|
= 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
|
error[E0658]: using `_` for array lengths is unstable
|
||||||
--> $DIR/issue-95307.rs:7:28
|
--> $DIR/issue-95307.rs:7:28
|
||||||
|
|
|
|
||||||
|
@ -18,12 +24,6 @@ LL | async fn new() -> [u8; _];
|
||||||
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
|
= 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
|
= 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
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0658, E0706.
|
Some errors have detailed explanations: E0658, E0706.
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
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: in expressions, `_` can only be used on the left-hand side of an assignment
|
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:11:27
|
||||||
|
|
|
|
||||||
LL | let _x: [u8; 3] = [0; _];
|
LL | let _x: [u8; 3] = [0; _];
|
||||||
| ^ `_` not allowed here
|
| ^ `_` 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:14:18
|
||||||
|
|
|
||||||
|
LL | let _y: [u8; _] = [0; 3];
|
||||||
|
| ^ `_` not allowed here
|
||||||
|
|
||||||
error[E0658]: using `_` for array lengths is unstable
|
error[E0658]: using `_` for array lengths is unstable
|
||||||
--> $DIR/feature-gate-generic_arg_infer.rs:14:18
|
--> $DIR/feature-gate-generic_arg_infer.rs:14:18
|
||||||
|
|
|
|
||||||
|
@ -21,12 +18,10 @@ LL | let _y: [u8; _] = [0; 3];
|
||||||
|
|
|
|
||||||
= note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
|
= 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
|
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
|
||||||
|
help: consider adding an array length
|
||||||
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];
|
LL | let _y: [u8; 3] = [0; 3];
|
||||||
| ^ `_` not allowed here
|
| ~
|
||||||
|
|
||||||
error[E0747]: type provided when a constant was expected
|
error[E0747]: type provided when a constant was expected
|
||||||
--> $DIR/feature-gate-generic_arg_infer.rs:20:20
|
--> $DIR/feature-gate-generic_arg_infer.rs:20:20
|
||||||
|
@ -37,6 +32,15 @@ LL | let _x = foo::<_>([1,2]);
|
||||||
= help: const arguments cannot yet be inferred with `_`
|
= help: const arguments cannot yet be inferred with `_`
|
||||||
= help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
|
= 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
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0658, E0747.
|
Some errors have detailed explanations: E0658, E0747.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue