From f2acafe9e280bc234a06fcd5f6e9a55dac109914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 7 Apr 2023 09:00:27 +0200 Subject: [PATCH] suggest adding const param --- compiler/rustc_resolve/src/late.rs | 4 +- .../rustc_resolve/src/late/diagnostics.rs | 15 +++-- .../missing-items/missing-const-parameter.rs | 24 +++++++ .../missing-const-parameter.stderr | 64 +++++++++++++++++++ 4 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 tests/ui/missing/missing-items/missing-const-parameter.rs create mode 100644 tests/ui/missing/missing-items/missing-const-parameter.stderr 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 ` 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] = ¶m.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; + +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; N]) {} +//~^ ERROR cannot find value `N` in this scope +//~| HELP you might be missing a const parameter + +struct Image([[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 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(_: 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(_: [u8; N]) {} + | +++++++++++++++++++++ + +error[E0425]: cannot find value `N` in this scope + --> $DIR/missing-const-parameter.rs:15:20 + | +LL | fn func2(_: [T; N]) {} + | ^ not found in this scope + | +help: you might be missing a const parameter + | +LL | fn func2(_: [T; N]) {} + | +++++++++++++++++++++ + +error[E0425]: cannot find value `C` in this scope + --> $DIR/missing-const-parameter.rs:19:37 + | +LL | struct Image([[u32; C]; R]); + | - ^ + | | + | similarly named const parameter `R` defined here + | +help: a const parameter with a similar name exists + | +LL | struct Image([[u32; R]; R]); + | ~ +help: you might be missing a const parameter + | +LL | struct Image([[u32; C]; R]); + | +++++++++++++++++++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0425`.