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
This commit is contained in:
commit
56e0626836
@ -3467,8 +3467,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||||||
sugg.to_string(),
|
sugg.to_string(),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
))
|
))
|
||||||
} else if res.is_none() && matches!(source, PathSource::Type) {
|
} else if res.is_none() && let PathSource::Type | PathSource::Expr(_) = source {
|
||||||
this.report_missing_type_error(path)
|
this.suggest_adding_generic_parameter(path, source)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -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,
|
&self,
|
||||||
path: &[Segment],
|
path: &[Segment],
|
||||||
|
source: PathSource<'_>,
|
||||||
) -> Option<(Span, &'static str, String, Applicability)> {
|
) -> Option<(Span, &'static str, String, Applicability)> {
|
||||||
let (ident, span) = match path {
|
let (ident, span) = match path {
|
||||||
[segment]
|
[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
|
// 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: kind @ ItemKind::Impl(..), .. }), true, true)
|
||||||
| (Some(Item { kind, .. }), false, _) => {
|
| (Some(Item { kind, .. }), false, _) => {
|
||||||
// Likely missing type parameter.
|
|
||||||
if let Some(generics) = kind.generics() {
|
if let Some(generics) = kind.generics() {
|
||||||
if span.overlaps(generics.span) {
|
if span.overlaps(generics.span) {
|
||||||
// Avoid the following:
|
// Avoid the following:
|
||||||
@ -2161,7 +2161,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||||||
// | not found in this scope
|
// | not found in this scope
|
||||||
return None;
|
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, sugg) = if let [.., param] = &generics.params[..] {
|
||||||
let span = if let [.., bound] = ¶m.bounds[..] {
|
let span = if let [.., bound] = ¶m.bounds[..] {
|
||||||
bound.span()
|
bound.span()
|
||||||
@ -2172,9 +2177,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
param.ident.span
|
param.ident.span
|
||||||
};
|
};
|
||||||
(span, format!(", {}", ident))
|
(span, format!(", {sugg}"))
|
||||||
} else {
|
} else {
|
||||||
(generics.span, format!("<{}>", ident))
|
(generics.span, format!("<{sugg}>"))
|
||||||
};
|
};
|
||||||
// Do not suggest if this is coming from macro expansion.
|
// Do not suggest if this is coming from macro expansion.
|
||||||
if span.can_be_used_for_suggestions() {
|
if span.can_be_used_for_suggestions() {
|
||||||
|
24
tests/ui/missing/missing-items/missing-const-parameter.rs
Normal file
24
tests/ui/missing/missing-items/missing-const-parameter.rs
Normal file
@ -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() {}
|
@ -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`.
|
Loading…
x
Reference in New Issue
Block a user