Skip to content

Commit e94d192

Browse files
committed
fix for #139999
1 parent 49e5e4e commit e94d192

File tree

10 files changed

+76
-38
lines changed

10 files changed

+76
-38
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -2764,14 +2764,39 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
27642764

27652765
let (msg, sugg) = match source {
27662766
PathSource::Type | PathSource::PreciseCapturingArg(TypeNS) => {
2767-
("you might be missing a type parameter", ident)
2767+
("you might be missing a type parameter", ident.clone())
27682768
}
27692769
PathSource::Expr(_) | PathSource::PreciseCapturingArg(ValueNS) => (
27702770
"you might be missing a const parameter",
27712771
format!("const {ident}: /* Type */"),
27722772
),
27732773
_ => return None,
27742774
};
2775+
2776+
// Heuristically determine whether a type name is likely intended to be a generic.
2777+
//
2778+
// We apply three rules:
2779+
// 1. Short names (like `T`, `U`, `E`) are common for generics.
2780+
// 2. Certain well-known names (e.g., `Item`, `Output`, `Error`) are commonly used as generics.
2781+
// 3. Names in UpperCamelCase are more likely to be concrete types.
2782+
//
2783+
// This approach may produce false positives or negatives, but works well in most cases.
2784+
2785+
let common_generic_names: &[&str] = &[
2786+
"Item", "Output", "Error", "Target", "Value", "Args",
2787+
"Res", "Ret", "This", "Iter", "Type",
2788+
];
2789+
let is_common_generic = common_generic_names.contains(&&*ident);
2790+
let looks_like_camel_case = ident
2791+
.chars()
2792+
.next()
2793+
.is_some_and(|c| c.is_uppercase())
2794+
&& ident.chars().skip(1).any(|c| c.is_lowercase());
2795+
2796+
// If it's not a known generic name and looks like a concrete type, skip the suggestion.
2797+
if !is_common_generic && looks_like_camel_case && ident.len() > 3 {
2798+
return None;
2799+
}
27752800
let (span, sugg) = if let [.., param] = &generics.params[..] {
27762801
let span = if let [.., bound] = &param.bounds[..] {
27772802
bound.span()

tests/ui/const-generics/generic_const_exprs/issue-109141.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ error[E0425]: cannot find value `HashesEntryLEN` in this scope
33
|
44
LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
55
| ^^^^^^^^^^^^^^ not found in this scope
6-
|
7-
help: you might be missing a const parameter
8-
|
9-
LL | struct EntriesBuffer<const HashesEntryLEN: /* Type */>(Box<[[u8; HashesEntryLEN]; 5]>);
10-
| ++++++++++++++++++++++++++++++++++
116

127
error: aborting due to 1 previous error
138

tests/ui/consts/error-is-freeze.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ error[E0412]: cannot find type `UndefinedType` in this scope
33
|
44
LL | foo: Option<UndefinedType>,
55
| ^^^^^^^^^^^^^ not found in this scope
6-
|
7-
help: you might be missing a type parameter
8-
|
9-
LL | struct MyStruct<UndefinedType> {
10-
| +++++++++++++++
116

127
error: aborting due to 1 previous error
138

tests/ui/issues/issue-58712.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ error[E0412]: cannot find type `DeviceId` in this scope
33
|
44
LL | impl<H> AddrVec<H, DeviceId> {
55
| ^^^^^^^^ not found in this scope
6-
|
7-
help: you might be missing a type parameter
8-
|
9-
LL | impl<H, DeviceId> AddrVec<H, DeviceId> {
10-
| ++++++++++
116

127
error[E0412]: cannot find type `DeviceId` in this scope
138
--> $DIR/issue-58712.rs:8:29

tests/ui/layout/thaw-transmute-invalid-enum.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@ error[E0412]: cannot find type `Subset` in this scope
33
|
44
LL | assert::is_transmutable::<Superset, Subset>();
55
| ^^^^^^ not found in this scope
6-
|
7-
help: you might be missing a type parameter
8-
|
9-
LL | fn test<Subset>() {
10-
| ++++++++
116

127
error[E0517]: attribute should be applied to a struct or union
138
--> $DIR/thaw-transmute-invalid-enum.rs:21:11

tests/ui/missing/missing-items/missing-type-parameter.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1-
fn foo<X>() { }
1+
fn foo<X>() {}
2+
3+
fn do_something() -> Option<ForgotToImport> {
4+
//~^ cannot find type `ForgotToImport` in this scope [E0412]
5+
None
6+
}
7+
8+
fn do_something_T() -> Option<T> {
9+
//~^ cannot find type `T` in this scope [E0412]
10+
None
11+
}
12+
13+
fn do_something_Type() -> Option<Type> {
14+
//~^ cannot find type `Type` in this scope [E0412]
15+
None
16+
}
217

318
fn main() {
419
foo(); //~ ERROR type annotations needed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
1+
error[E0412]: cannot find type `ForgotToImport` in this scope
2+
--> $DIR/missing-type-parameter.rs:3:29
3+
|
4+
LL | fn do_something() -> Option<ForgotToImport> {
5+
| ^^^^^^^^^^^^^^ not found in this scope
6+
7+
error[E0412]: cannot find type `T` in this scope
8+
--> $DIR/missing-type-parameter.rs:8:31
9+
|
10+
LL | fn do_something_T() -> Option<T> {
11+
| ^ not found in this scope
12+
|
13+
help: you might be missing a type parameter
14+
|
15+
LL | fn do_something_T<T>() -> Option<T> {
16+
| +++
17+
18+
error[E0412]: cannot find type `Type` in this scope
19+
--> $DIR/missing-type-parameter.rs:13:34
20+
|
21+
LL | fn do_something_Type() -> Option<Type> {
22+
| ^^^^ not found in this scope
23+
|
24+
help: you might be missing a type parameter
25+
|
26+
LL | fn do_something_Type<Type>() -> Option<Type> {
27+
| ++++++
28+
129
error[E0282]: type annotations needed
2-
--> $DIR/missing-type-parameter.rs:4:5
30+
--> $DIR/missing-type-parameter.rs:19:5
331
|
432
LL | foo();
533
| ^^^ cannot infer type of the type parameter `X` declared on the function `foo`
@@ -9,6 +37,7 @@ help: consider specifying the generic argument
937
LL | foo::<X>();
1038
| +++++
1139

12-
error: aborting due to 1 previous error
40+
error: aborting due to 4 previous errors
1341

14-
For more information about this error, try `rustc --explain E0282`.
42+
Some errors have detailed explanations: E0282, E0412.
43+
For more information about an error, try `rustc --explain E0282`.

tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr

+1-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ error[E0412]: cannot find type `NonExistent` in this scope
1010
LL | struct Foo(NonExistent);
1111
| ^^^^^^^^^^^ not found in this scope
1212
|
13-
help: you might be missing a type parameter
14-
|
15-
LL | struct Foo<NonExistent>(NonExistent);
16-
| +++++++++++++
13+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1714

1815
error[E0658]: `impl Trait` in type aliases is unstable
1916
--> $DIR/issue-119493-type-error-ice.rs:9:14

tests/ui/traits/issue-50480.stderr

+1-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ error[E0412]: cannot find type `NotDefined` in this scope
3232
LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
3333
| ^^^^^^^^^^ not found in this scope
3434
|
35-
help: you might be missing a type parameter
36-
|
37-
LL | struct Foo<NotDefined>(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
38-
| ++++++++++++
35+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
3936

4037
error[E0412]: cannot find type `N` in this scope
4138
--> $DIR/issue-50480.rs:14:18

tests/ui/traits/trait-selection-ice-84727.stderr

-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@ error[E0412]: cannot find type `NewBg` in this scope
2121
|
2222
LL | fn over(self) -> Cell<NewBg> {
2323
| ^^^^^ not found in this scope
24-
|
25-
help: you might be missing a type parameter
26-
|
27-
LL | impl<'b, TopFg, TopBg, BottomFg, BottomBg, NewBg> Over<&Cell<BottomFg, BottomBg>, ()>
28-
| +++++++
2924

3025
error[E0308]: mismatched types
3126
--> $DIR/trait-selection-ice-84727.rs:21:22

0 commit comments

Comments
 (0)