about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2023-04-07 09:00:27 +0200
committerLeón Orell Valerian Liehr <me@fmease.dev>2023-04-07 09:11:53 +0200
commitf2acafe9e280bc234a06fcd5f6e9a55dac109914 (patch)
tree1f17b67d7bf051d483950edbb3330d75e4ef77c6
parent32ea4bb9e3785ae76660b1303e821255c02aad1a (diff)
downloadrust-f2acafe9e280bc234a06fcd5f6e9a55dac109914.tar.gz
rust-f2acafe9e280bc234a06fcd5f6e9a55dac109914.zip
suggest adding const param
-rw-r--r--compiler/rustc_resolve/src/late.rs4
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs15
-rw-r--r--tests/ui/missing/missing-items/missing-const-parameter.rs24
-rw-r--r--tests/ui/missing/missing-items/missing-const-parameter.stderr64
4 files changed, 100 insertions, 7 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 19f46d45af6..10f0fc2a7e3 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3458,8 +3458,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         sugg.to_string(),
                         Applicability::MaybeIncorrect,
                     ))
-                } else if res.is_none() && matches!(source, PathSource::Type) {
-                    this.report_missing_type_error(path)
+                } else if res.is_none() && let PathSource::Type | PathSource::Expr(_) = source {
+                    this.suggest_adding_generic_parameter(path, source)
                 } else {
                     None
                 };
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index df7681dc426..37fbfad2de6 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2110,9 +2110,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         }
     }
 
-    pub(crate) fn report_missing_type_error(
+    pub(crate) fn suggest_adding_generic_parameter(
         &self,
         path: &[Segment],
+        source: PathSource<'_>,
     ) -> Option<(Span, &'static str, String, Applicability)> {
         let (ident, span) = match path {
             [segment]
@@ -2148,7 +2149,6 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
             // Without the 2nd `true`, we'd suggest `impl <T>` for `impl T` when a type `T` isn't found
             | (Some(Item { kind: kind @ ItemKind::Impl(..), .. }), true, true)
             | (Some(Item { kind, .. }), false, _) => {
-                // Likely missing type parameter.
                 if let Some(generics) = kind.generics() {
                     if span.overlaps(generics.span) {
                         // Avoid the following:
@@ -2161,7 +2161,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         //   |           not found in this scope
                         return None;
                     }
-                    let msg = "you might be missing a type parameter";
+
+                    let (msg, sugg) = match source {
+                        PathSource::Type => ("you might be missing a type parameter", ident),
+                        PathSource::Expr(_) => ("you might be missing a const parameter", format!("const {ident}: /* Type */")),
+                        _ => return None,
+                    };
                     let (span, sugg) = if let [.., param] = &generics.params[..] {
                         let span = if let [.., bound] = &param.bounds[..] {
                             bound.span()
@@ -2172,9 +2177,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         } else {
                             param.ident.span
                         };
-                        (span, format!(", {}", ident))
+                        (span, format!(", {sugg}"))
                     } else {
-                        (generics.span, format!("<{}>", ident))
+                        (generics.span, format!("<{sugg}>"))
                     };
                     // Do not suggest if this is coming from macro expansion.
                     if span.can_be_used_for_suggestions() {
diff --git a/tests/ui/missing/missing-items/missing-const-parameter.rs b/tests/ui/missing/missing-items/missing-const-parameter.rs
new file mode 100644
index 00000000000..a3af88f2633
--- /dev/null
+++ b/tests/ui/missing/missing-items/missing-const-parameter.rs
@@ -0,0 +1,24 @@
+struct Struct<const N: usize>;
+
+impl Struct<{ N }> {}
+//~^ ERROR cannot find value `N` in this scope
+//~| HELP you might be missing a const parameter
+
+fn func0(_: Struct<{ N }>) {}
+//~^ ERROR cannot find value `N` in this scope
+//~| HELP you might be missing a const parameter
+
+fn func1(_: [u8; N]) {}
+//~^ ERROR cannot find value `N` in this scope
+//~| HELP you might be missing a const parameter
+
+fn func2<T>(_: [T; N]) {}
+//~^ ERROR cannot find value `N` in this scope
+//~| HELP you might be missing a const parameter
+
+struct Image<const R: usize>([[u32; C]; R]);
+//~^ ERROR cannot find value `C` in this scope
+//~| HELP a const parameter with a similar name exists
+//~| HELP you might be missing a const parameter
+
+fn main() {}
diff --git a/tests/ui/missing/missing-items/missing-const-parameter.stderr b/tests/ui/missing/missing-items/missing-const-parameter.stderr
new file mode 100644
index 00000000000..d9fea130651
--- /dev/null
+++ b/tests/ui/missing/missing-items/missing-const-parameter.stderr
@@ -0,0 +1,64 @@
+error[E0425]: cannot find value `N` in this scope
+  --> $DIR/missing-const-parameter.rs:3:15
+   |
+LL | impl Struct<{ N }> {}
+   |               ^ not found in this scope
+   |
+help: you might be missing a const parameter
+   |
+LL | impl<const N: /* Type */> Struct<{ N }> {}
+   |     +++++++++++++++++++++
+
+error[E0425]: cannot find value `N` in this scope
+  --> $DIR/missing-const-parameter.rs:7:22
+   |
+LL | fn func0(_: Struct<{ N }>) {}
+   |                      ^ not found in this scope
+   |
+help: you might be missing a const parameter
+   |
+LL | fn func0<const N: /* Type */>(_: Struct<{ N }>) {}
+   |         +++++++++++++++++++++
+
+error[E0425]: cannot find value `N` in this scope
+  --> $DIR/missing-const-parameter.rs:11:18
+   |
+LL | fn func1(_: [u8; N]) {}
+   |                  ^ not found in this scope
+   |
+help: you might be missing a const parameter
+   |
+LL | fn func1<const N: /* Type */>(_: [u8; N]) {}
+   |         +++++++++++++++++++++
+
+error[E0425]: cannot find value `N` in this scope
+  --> $DIR/missing-const-parameter.rs:15:20
+   |
+LL | fn func2<T>(_: [T; N]) {}
+   |                    ^ not found in this scope
+   |
+help: you might be missing a const parameter
+   |
+LL | fn func2<T, const N: /* Type */>(_: [T; N]) {}
+   |           +++++++++++++++++++++
+
+error[E0425]: cannot find value `C` in this scope
+  --> $DIR/missing-const-parameter.rs:19:37
+   |
+LL | struct Image<const R: usize>([[u32; C]; R]);
+   |                    -                ^
+   |                    |
+   |                    similarly named const parameter `R` defined here
+   |
+help: a const parameter with a similar name exists
+   |
+LL | struct Image<const R: usize>([[u32; R]; R]);
+   |                                     ~
+help: you might be missing a const parameter
+   |
+LL | struct Image<const R: usize, const C: /* Type */>([[u32; C]; R]);
+   |                            +++++++++++++++++++++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0425`.