diff options
| author | bors <bors@rust-lang.org> | 2023-04-09 10:54:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-04-09 10:54:04 +0000 |
| commit | 56e0626836d92973cd12cb505179eef9795efc61 (patch) | |
| tree | e4937c502e8bd7ae5aa4933d44bacff7564507f9 | |
| parent | 709a97fffec5e09cb5feca894c394ee80c2680ba (diff) | |
| parent | f2acafe9e280bc234a06fcd5f6e9a55dac109914 (diff) | |
| download | rust-56e0626836d92973cd12cb505179eef9795efc61.tar.gz rust-56e0626836d92973cd12cb505179eef9795efc61.zip | |
Auto merge of #110041 - fmease:diag-sugg-adding-const-param, r=compiler-errors
Suggest defining const parameter when appropriate Helps a bit with #91119. Following #105523's lead, I use placeholder `/* Type */` instead of `_` in the suggestion. It should be easier for newcomers to parse. `@rustbot` label A-diagnostics r? diagnostics
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 15 | ||||
| -rw-r--r-- | tests/ui/missing/missing-items/missing-const-parameter.rs | 24 | ||||
| -rw-r--r-- | tests/ui/missing/missing-items/missing-const-parameter.stderr | 64 |
4 files changed, 100 insertions, 7 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b1a696d093e..b3f66c4ba33 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3467,8 +3467,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] = ¶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<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`. |
