mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
suggest adding an array length if possible
This commit is contained in:
parent
0068b8bf4b
commit
4d1b5f0d99
@ -49,7 +49,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};
|
||||
@ -2236,7 +2236,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))
|
||||
}
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
@ -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};
|
||||
@ -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_verbose(
|
||||
span,
|
||||
"consider adding an array length",
|
||||
array_len,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr_const_block(
|
||||
@ -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() {
|
||||
|
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: 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
|
||||
|
|
||||
@ -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.
|
||||
|
@ -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
|
||||
--> $DIR/feature-gate-generic_arg_infer.rs:11:27
|
||||
|
|
||||
LL | let _x: [u8; 3] = [0; _];
|
||||
| ^ `_` 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
|
||||
--> $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
|
||||
= 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
|
||||
help: consider adding an array length
|
||||
|
|
||||
LL | let _y: [u8; _] = [0; 3];
|
||||
| ^ `_` not allowed here
|
||||
LL | let _y: [u8; 3] = [0; 3];
|
||||
| ~
|
||||
|
||||
error[E0747]: type provided when a constant was expected
|
||||
--> $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: 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.
|
||||
|
Loading…
Reference in New Issue
Block a user