diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 13e457507cf..03b578d4ade 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -6,7 +6,10 @@ use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{PathResult, PathSource, Segment}; use rustc_ast::visit::FnKind; -use rustc_ast::{self as ast, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind}; +use rustc_ast::{ + self as ast, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind, NodeId, Path, Ty, + TyKind, +}; use rustc_ast_pretty::pprust::path_segment_to_string; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, SuggestionStyle}; @@ -1600,8 +1603,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { if !self.diagnostic_metadata.currently_processing_generics && !single_uppercase_char { return None; } - match (self.diagnostic_metadata.current_item, single_uppercase_char) { - (Some(Item { kind: ItemKind::Fn(..), ident, .. }), _) if ident.name == sym::main => { + match (self.diagnostic_metadata.current_item, single_uppercase_char, self.diagnostic_metadata.currently_processing_generics) { + (Some(Item { kind: ItemKind::Fn(..), ident, .. }), _, _) if ident.name == sym::main => { // Ignore `fn main()` as we don't want to suggest `fn main()` } ( @@ -1613,9 +1616,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { | kind @ ItemKind::Union(..), .. }), - true, + true, _ ) - | (Some(Item { kind, .. }), false) => { + // 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) { @@ -1633,6 +1638,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let (span, sugg) = if let [.., param] = &generics.params[..] { let span = if let [.., bound] = ¶m.bounds[..] { bound.span() + } else if let GenericParam { + kind: GenericParamKind::Const { ty, kw_span: _, default }, .. + } = param { + default.as_ref().map(|def| def.value.span).unwrap_or(ty.span) } else { param.ident.span }; diff --git a/src/test/ui/const-generics/diagnostics.stderr b/src/test/ui/const-generics/diagnostics.stderr index c8ee6ad61ec..2e3132c2eb7 100644 --- a/src/test/ui/const-generics/diagnostics.stderr +++ b/src/test/ui/const-generics/diagnostics.stderr @@ -5,7 +5,16 @@ LL | struct A; | ---------------------- similarly named struct `A` defined here LL | trait Foo {} LL | impl Foo for A {} - | ^ help: a struct with a similar name exists: `A` + | ^ + | +help: a struct with a similar name exists + | +LL | impl Foo for A {} + | ^ +help: you might be missing a type parameter + | +LL | impl Foo for A {} + | ^^^ error[E0412]: cannot find type `T` in this scope --> $DIR/diagnostics.rs:16:32 @@ -14,7 +23,16 @@ LL | struct A; | ---------------------- similarly named struct `A` defined here ... LL | impl Foo for C {} - | ^ help: a struct with a similar name exists: `A` + | ^ + | +help: a struct with a similar name exists + | +LL | impl Foo for C {} + | ^ +help: you might be missing a type parameter + | +LL | impl Foo for C {} + | ^^^ error[E0747]: unresolved item provided when a constant was expected --> $DIR/diagnostics.rs:7:16 diff --git a/src/test/ui/missing/missing-items/missing-type-parameter2.rs b/src/test/ui/missing/missing-items/missing-type-parameter2.rs new file mode 100644 index 00000000000..15dc5ef797b --- /dev/null +++ b/src/test/ui/missing/missing-items/missing-type-parameter2.rs @@ -0,0 +1,22 @@ +#![allow(incomplete_features)] +#![feature(const_generics_defaults)] + +struct X(); + +impl X {} +//~^ ERROR cannot find type `N` in this scope +//~| ERROR unresolved item provided when a constant was expected +impl X {} +//~^ ERROR cannot find type `N` in this scope +//~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions +//~| ERROR unresolved item provided when a constant was expected + +fn foo(_: T) where T: Send {} +//~^ ERROR cannot find type `T` in this scope +//~| ERROR cannot find type `T` in this scope + +fn bar(_: A) {} +//~^ ERROR cannot find type `A` in this scope + +fn main() { +} diff --git a/src/test/ui/missing/missing-items/missing-type-parameter2.stderr b/src/test/ui/missing/missing-items/missing-type-parameter2.stderr new file mode 100644 index 00000000000..985a9bb2a3f --- /dev/null +++ b/src/test/ui/missing/missing-items/missing-type-parameter2.stderr @@ -0,0 +1,121 @@ +error[E0412]: cannot find type `N` in this scope + --> $DIR/missing-type-parameter2.rs:6:8 + | +LL | struct X(); + | ------------------------ similarly named struct `X` defined here +LL | +LL | impl X {} + | ^ + | +help: a struct with a similar name exists + | +LL | impl X {} + | ^ +help: you might be missing a type parameter + | +LL | impl X {} + | ^^^ + +error[E0412]: cannot find type `N` in this scope + --> $DIR/missing-type-parameter2.rs:9:28 + | +LL | impl X {} + | - ^ + | | + | similarly named type parameter `T` defined here + | +help: a type parameter with a similar name exists + | +LL | impl X {} + | ^ +help: you might be missing a type parameter + | +LL | impl X {} + | ^^^ + +error[E0412]: cannot find type `T` in this scope + --> $DIR/missing-type-parameter2.rs:14:20 + | +LL | struct X(); + | ------------------------ similarly named struct `X` defined here +... +LL | fn foo(_: T) where T: Send {} + | ^ + | +help: a struct with a similar name exists + | +LL | fn foo(_: T) where X: Send {} + | ^ +help: you might be missing a type parameter + | +LL | fn foo(_: T) where T: Send {} + | ^^^ + +error[E0412]: cannot find type `T` in this scope + --> $DIR/missing-type-parameter2.rs:14:11 + | +LL | struct X(); + | ------------------------ similarly named struct `X` defined here +... +LL | fn foo(_: T) where T: Send {} + | ^ + | +help: a struct with a similar name exists + | +LL | fn foo(_: X) where T: Send {} + | ^ +help: you might be missing a type parameter + | +LL | fn foo(_: T) where T: Send {} + | ^^^ + +error[E0412]: cannot find type `A` in this scope + --> $DIR/missing-type-parameter2.rs:18:24 + | +LL | struct X(); + | ------------------------ similarly named struct `X` defined here +... +LL | fn bar(_: A) {} + | ^ + | +help: a struct with a similar name exists + | +LL | fn bar(_: X) {} + | ^ +help: you might be missing a type parameter + | +LL | fn bar(_: A) {} + | ^^^ + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/missing-type-parameter2.rs:6:8 + | +LL | impl X {} + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | impl X<{ N }> {} + | ^ ^ + +error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/missing-type-parameter2.rs:9:15 + | +LL | impl X {} + | ^ + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/missing-type-parameter2.rs:9:28 + | +LL | impl X {} + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | impl X<{ N }> {} + | ^ ^ + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0412, E0747. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/traits/issue-75627.stderr b/src/test/ui/traits/issue-75627.stderr index 92d9ac0f84c..432ddf2dcdb 100644 --- a/src/test/ui/traits/issue-75627.stderr +++ b/src/test/ui/traits/issue-75627.stderr @@ -2,7 +2,9 @@ error[E0412]: cannot find type `T` in this scope --> $DIR/issue-75627.rs:3:26 | LL | unsafe impl Send for Foo {} - | ^ not found in this scope + | - ^ not found in this scope + | | + | help: you might be missing a type parameter: `` error: aborting due to previous error diff --git a/src/test/ui/traits/issue-78372.stderr b/src/test/ui/traits/issue-78372.stderr index 9267e838cea..e63740c4ea9 100644 --- a/src/test/ui/traits/issue-78372.stderr +++ b/src/test/ui/traits/issue-78372.stderr @@ -13,9 +13,18 @@ error[E0412]: cannot find type `U` in this scope --> $DIR/issue-78372.rs:3:31 | LL | impl DispatchFromDyn> for T {} - | - ^ help: a type parameter with a similar name exists: `T` + | - ^ | | | similarly named type parameter `T` defined here + | +help: a type parameter with a similar name exists + | +LL | impl DispatchFromDyn> for T {} + | ^ +help: you might be missing a type parameter + | +LL | impl DispatchFromDyn> for T {} + | ^^^ error[E0412]: cannot find type `MISC` in this scope --> $DIR/issue-78372.rs:3:34