From 4d1b5f0d997b567b558a3fb88bd4724ba6e32f32 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Tue, 16 Aug 2022 00:16:14 +0900 Subject: suggest adding an array length if possible --- compiler/rustc_ast_lowering/src/lib.rs | 4 ++-- compiler/rustc_errors/src/lib.rs | 1 + compiler/rustc_typeck/src/check/expr.rs | 41 ++++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) (limited to 'compiler') diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 38d30d0ffde..bf9034850c9 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -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)) } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 15c1858023d..4d4d44580b7 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -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) {} diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 6a6c03a8cba..34cc5be8ad5 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -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() { -- cgit 1.4.1-3-g733a5 From 12e609ba3cb7a395601c3b6762682248b0a325ad Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Tue, 16 Aug 2022 03:42:58 +0900 Subject: use `span_suggestion` instead of `span_suggestion_verbose` --- compiler/rustc_typeck/src/check/expr.rs | 4 ++-- .../ui/array-slice-vec/suggest-array-length.stderr | 18 +++--------------- .../feature-gate-generic_arg_infer.normal.stderr | 6 +----- 3 files changed, 6 insertions(+), 22 deletions(-) (limited to 'compiler') diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 34cc5be8ad5..9c2fdd87516 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1328,9 +1328,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) { Some(mut err) => { - err.span_suggestion_verbose( + err.span_suggestion( span, - "consider adding an array length", + "consider specifying the array length", array_len, Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/array-slice-vec/suggest-array-length.stderr b/src/test/ui/array-slice-vec/suggest-array-length.stderr index fdf6f82649a..9000f716028 100644 --- a/src/test/ui/array-slice-vec/suggest-array-length.stderr +++ b/src/test/ui/array-slice-vec/suggest-array-length.stderr @@ -20,40 +20,28 @@ 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 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]; - | ^ + | ^ help: consider specifying the array length: `3` | = note: see issue #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]; - | ^ + | ^ help: consider specifying the array length: `3` | = note: see issue #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 diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr index 4fca436827e..56123a983b3 100644 --- a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr +++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr @@ -14,14 +14,10 @@ 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 for more information = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable -help: consider adding an array length - | -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 -- cgit 1.4.1-3-g733a5