about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-08-16 06:05:59 +0200
committerGitHub <noreply@github.com>2022-08-16 06:05:59 +0200
commit76dd1663d9bcad3d9d708af1625412d2ef87fb19 (patch)
tree21481c463c974640ac88ef9580438e999785d700 /compiler
parentfc735b05b88d9310db779ba7d2bf8829b7268623 (diff)
parent12e609ba3cb7a395601c3b6762682248b0a325ad (diff)
downloadrust-76dd1663d9bcad3d9d708af1625412d2ef87fb19.tar.gz
rust-76dd1663d9bcad3d9d708af1625412d2ef87fb19.zip
Rollup merge of #100590 - TaKO8Ki:suggest-adding-array-length, r=compiler-errors
Suggest adding an array length if possible

fixes #100448
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs4
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs41
3 files changed, 41 insertions, 5 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 056f9ca08f8..c1c7a7ddd91 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -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};
@@ -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))
                 }
             }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index d2eb4f212eb..395bf5aad01 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..9c2fdd87516 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(
+                            span,
+                            "consider specifying the 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() {