diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index d4fe446cc9f76..d0033089b5ceb 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2764,7 +2764,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
let (msg, sugg) = match source {
PathSource::Type | PathSource::PreciseCapturingArg(TypeNS) => {
- ("you might be missing a type parameter", ident)
+ ("you might be missing a type parameter", ident.clone())
}
PathSource::Expr(_) | PathSource::PreciseCapturingArg(ValueNS) => (
"you might be missing a const parameter",
@@ -2772,6 +2772,31 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
),
_ => return None,
};
+
+ // Heuristically determine whether a type name is likely intended to be a generic.
+ //
+ // We apply three rules:
+ // 1. Short names (like `T`, `U`, `E`) are common for generics.
+ // 2. Certain well-known names (e.g., `Item`, `Output`, `Error`) are commonly used as generics.
+ // 3. Names in UpperCamelCase are more likely to be concrete types.
+ //
+ // This approach may produce false positives or negatives, but works well in most cases.
+
+ let common_generic_names: &[&str] = &[
+ "Item", "Output", "Error", "Target", "Value", "Args",
+ "Res", "Ret", "This", "Iter", "Type",
+ ];
+ let is_common_generic = common_generic_names.contains(&&*ident);
+ let looks_like_camel_case = ident
+ .chars()
+ .next()
+ .is_some_and(|c| c.is_uppercase())
+ && ident.chars().skip(1).any(|c| c.is_lowercase());
+
+ // If it's not a known generic name and looks like a concrete type, skip the suggestion.
+ if !is_common_generic && looks_like_camel_case && ident.len() > 3 {
+ return None;
+ }
let (span, sugg) = if let [.., param] = &generics.params[..] {
let span = if let [.., bound] = ¶m.bounds[..] {
bound.span()
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
index fcbd690459972..133d659678810 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
@@ -3,11 +3,6 @@ error[E0425]: cannot find value `HashesEntryLEN` in this scope
|
LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
| ^^^^^^^^^^^^^^ not found in this scope
- |
-help: you might be missing a const parameter
- |
-LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
- | ++++++++++++++++++++++++++++++++++
error: aborting due to 1 previous error
diff --git a/tests/ui/consts/error-is-freeze.stderr b/tests/ui/consts/error-is-freeze.stderr
index f3bfd1ea5e293..da0f31cf38c7b 100644
--- a/tests/ui/consts/error-is-freeze.stderr
+++ b/tests/ui/consts/error-is-freeze.stderr
@@ -3,11 +3,6 @@ error[E0412]: cannot find type `UndefinedType` in this scope
|
LL | foo: Option,
| ^^^^^^^^^^^^^ not found in this scope
- |
-help: you might be missing a type parameter
- |
-LL | struct MyStruct {
- | +++++++++++++++
error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-58712.stderr b/tests/ui/issues/issue-58712.stderr
index f4bd4d1e826a0..6164ad7ee19b2 100644
--- a/tests/ui/issues/issue-58712.stderr
+++ b/tests/ui/issues/issue-58712.stderr
@@ -3,11 +3,6 @@ error[E0412]: cannot find type `DeviceId` in this scope
|
LL | impl AddrVec {
| ^^^^^^^^ not found in this scope
- |
-help: you might be missing a type parameter
- |
-LL | impl AddrVec {
- | ++++++++++
error[E0412]: cannot find type `DeviceId` in this scope
--> $DIR/issue-58712.rs:8:29
diff --git a/tests/ui/layout/thaw-transmute-invalid-enum.stderr b/tests/ui/layout/thaw-transmute-invalid-enum.stderr
index d12fc4694e0ab..261ba7592a8f3 100644
--- a/tests/ui/layout/thaw-transmute-invalid-enum.stderr
+++ b/tests/ui/layout/thaw-transmute-invalid-enum.stderr
@@ -3,11 +3,6 @@ error[E0412]: cannot find type `Subset` in this scope
|
LL | assert::is_transmutable::();
| ^^^^^^ not found in this scope
- |
-help: you might be missing a type parameter
- |
-LL | fn test() {
- | ++++++++
error[E0517]: attribute should be applied to a struct or union
--> $DIR/thaw-transmute-invalid-enum.rs:21:11
diff --git a/tests/ui/missing/missing-items/missing-type-parameter.rs b/tests/ui/missing/missing-items/missing-type-parameter.rs
index 8a64053a4f003..f5308fac3482a 100644
--- a/tests/ui/missing/missing-items/missing-type-parameter.rs
+++ b/tests/ui/missing/missing-items/missing-type-parameter.rs
@@ -1,4 +1,19 @@
-fn foo() { }
+fn foo() {}
+
+fn do_something() -> Option {
+ //~^ cannot find type `ForgotToImport` in this scope [E0412]
+ None
+}
+
+fn do_something_T() -> Option {
+ //~^ cannot find type `T` in this scope [E0412]
+ None
+}
+
+fn do_something_Type() -> Option {
+ //~^ cannot find type `Type` in this scope [E0412]
+ None
+}
fn main() {
foo(); //~ ERROR type annotations needed
diff --git a/tests/ui/missing/missing-items/missing-type-parameter.stderr b/tests/ui/missing/missing-items/missing-type-parameter.stderr
index 658e2c8e85eed..169b61dddb296 100644
--- a/tests/ui/missing/missing-items/missing-type-parameter.stderr
+++ b/tests/ui/missing/missing-items/missing-type-parameter.stderr
@@ -1,5 +1,33 @@
+error[E0412]: cannot find type `ForgotToImport` in this scope
+ --> $DIR/missing-type-parameter.rs:3:29
+ |
+LL | fn do_something() -> Option {
+ | ^^^^^^^^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `T` in this scope
+ --> $DIR/missing-type-parameter.rs:8:31
+ |
+LL | fn do_something_T() -> Option {
+ | ^ not found in this scope
+ |
+help: you might be missing a type parameter
+ |
+LL | fn do_something_T() -> Option {
+ | +++
+
+error[E0412]: cannot find type `Type` in this scope
+ --> $DIR/missing-type-parameter.rs:13:34
+ |
+LL | fn do_something_Type() -> Option {
+ | ^^^^ not found in this scope
+ |
+help: you might be missing a type parameter
+ |
+LL | fn do_something_Type() -> Option {
+ | ++++++
+
error[E0282]: type annotations needed
- --> $DIR/missing-type-parameter.rs:4:5
+ --> $DIR/missing-type-parameter.rs:19:5
|
LL | foo();
| ^^^ cannot infer type of the type parameter `X` declared on the function `foo`
@@ -9,6 +37,7 @@ help: consider specifying the generic argument
LL | foo::();
| +++++
-error: aborting due to 1 previous error
+error: aborting due to 4 previous errors
-For more information about this error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0282, E0412.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr
index 1c560aa2ca813..5e1d2a49bfab2 100644
--- a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr
+++ b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr
@@ -10,10 +10,7 @@ error[E0412]: cannot find type `NonExistent` in this scope
LL | struct Foo(NonExistent);
| ^^^^^^^^^^^ not found in this scope
|
-help: you might be missing a type parameter
- |
-LL | struct Foo(NonExistent);
- | +++++++++++++
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/issue-119493-type-error-ice.rs:9:14
diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr
index ed8c74e9bddcf..073ec307d4c07 100644
--- a/tests/ui/traits/issue-50480.stderr
+++ b/tests/ui/traits/issue-50480.stderr
@@ -32,10 +32,7 @@ error[E0412]: cannot find type `NotDefined` in this scope
LL | struct Foo(N, NotDefined, ::Item, Vec, String);
| ^^^^^^^^^^ not found in this scope
|
-help: you might be missing a type parameter
- |
-LL | struct Foo(N, NotDefined, ::Item, Vec, String);
- | ++++++++++++
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0412]: cannot find type `N` in this scope
--> $DIR/issue-50480.rs:14:18
diff --git a/tests/ui/traits/trait-selection-ice-84727.stderr b/tests/ui/traits/trait-selection-ice-84727.stderr
index d4bc4163897c4..39ab775f05a14 100644
--- a/tests/ui/traits/trait-selection-ice-84727.stderr
+++ b/tests/ui/traits/trait-selection-ice-84727.stderr
@@ -21,11 +21,6 @@ error[E0412]: cannot find type `NewBg` in this scope
|
LL | fn over(self) -> Cell {
| ^^^^^ not found in this scope
- |
-help: you might be missing a type parameter
- |
-LL | impl<'b, TopFg, TopBg, BottomFg, BottomBg, NewBg> Over<&Cell, ()>
- | +++++++
error[E0308]: mismatched types
--> $DIR/trait-selection-ice-84727.rs:21:22