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