Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit af45d8a

Browse files
committed
Suggest new type param on single char ident
Suggest new type parameter on single char uppercase ident even if it doesn't appear in a field's type parameter. Address comment in rust-lang#72641.
1 parent 4606168 commit af45d8a

File tree

4 files changed

+61
-15
lines changed

4 files changed

+61
-15
lines changed

src/librustc_resolve/late/diagnostics.rs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -919,20 +919,45 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
919919
&self,
920920
path: &[Segment],
921921
) -> Option<(Span, &'static str, String, Applicability)> {
922-
let ident = match path {
923-
[segment] if !segment.has_args => segment.ident,
922+
let (ident, span) = match path {
923+
[segment] if !segment.has_args => (segment.ident.to_string(), segment.ident.span),
924924
_ => return None,
925925
};
926-
match (
927-
self.diagnostic_metadata.current_item,
928-
self.diagnostic_metadata.currently_processing_generics,
929-
) {
930-
(Some(Item { kind: ItemKind::Fn(..), ident, .. }), true) if ident.name == sym::main => {
926+
let mut iter = ident.chars().map(|c| c.is_uppercase());
927+
let single_uppercase_char =
928+
matches!(iter.next(), Some(true)) && matches!(iter.next(), None);
929+
if !self.diagnostic_metadata.currently_processing_generics && !single_uppercase_char {
930+
return None;
931+
}
932+
match (self.diagnostic_metadata.current_item, single_uppercase_char) {
933+
(Some(Item { kind: ItemKind::Fn(..), ident, .. }), _) if ident.name == sym::main => {
931934
// Ignore `fn main()` as we don't want to suggest `fn main<T>()`
932935
}
933-
(Some(Item { kind, .. }), true) => {
936+
(
937+
Some(Item {
938+
kind:
939+
kind @ ItemKind::Fn(..)
940+
| kind @ ItemKind::Enum(..)
941+
| kind @ ItemKind::Struct(..)
942+
| kind @ ItemKind::Union(..),
943+
..
944+
}),
945+
true,
946+
)
947+
| (Some(Item { kind, .. }), false) => {
934948
// Likely missing type parameter.
935949
if let Some(generics) = kind.generics() {
950+
if span.overlaps(generics.span) {
951+
// Avoid the following:
952+
// error[E0405]: cannot find trait `A` in this scope
953+
// --> $DIR/typo-suggestion-named-underscore.rs:CC:LL
954+
// |
955+
// L | fn foo<T: A>(x: T) {} // Shouldn't suggest underscore
956+
// | ^- help: you might be missing a type parameter: `, A`
957+
// | |
958+
// | not found in this scope
959+
return None;
960+
}
936961
let msg = "you might be missing a type parameter";
937962
let (span, sugg) = if let [.., param] = &generics.params[..] {
938963
let span = if let [.., bound] = &param.bounds[..] {

src/test/ui/associated-types/associated-types-eq-1.stderr

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ error[E0412]: cannot find type `A` in this scope
44
LL | fn foo2<I: Foo>(x: I) {
55
| - similarly named type parameter `I` defined here
66
LL | let _: A = x.boo();
7-
| ^ help: a type parameter with a similar name exists: `I`
7+
| ^
8+
|
9+
help: a type parameter with a similar name exists
10+
|
11+
LL | let _: I = x.boo();
12+
| ^
13+
help: you might be missing a type parameter
14+
|
15+
LL | fn foo2<I: Foo, A>(x: I) {
16+
| ^^^
817

918
error: aborting due to previous error
1019

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
struct S {
2-
m: Vec<Hashmap<String, ()>>, //~ ERROR cannot find type `Hashmap` in this scope
1+
struct Struct {
2+
m: Vec<Someunknownname<String, ()>>, //~ ERROR cannot find type `Someunknownname` in this scope
3+
//~^ NOTE not found in this scope
4+
}
5+
struct OtherStruct { //~ HELP you might be missing a type parameter
6+
m: K, //~ ERROR cannot find type `K` in this scope
37
//~^ NOTE not found in this scope
48
}
59
fn main() {}
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
error[E0412]: cannot find type `Hashmap` in this scope
1+
error[E0412]: cannot find type `Someunknownname` in this scope
22
--> $DIR/type-not-found-in-adt-field.rs:2:12
33
|
4-
LL | m: Vec<Hashmap<String, ()>>,
5-
| ^^^^^^^ not found in this scope
4+
LL | m: Vec<Someunknownname<String, ()>>,
5+
| ^^^^^^^^^^^^^^^ not found in this scope
66

7-
error: aborting due to previous error
7+
error[E0412]: cannot find type `K` in this scope
8+
--> $DIR/type-not-found-in-adt-field.rs:6:8
9+
|
10+
LL | struct OtherStruct {
11+
| - help: you might be missing a type parameter: `<K>`
12+
LL | m: K,
13+
| ^ not found in this scope
14+
15+
error: aborting due to 2 previous errors
816

917
For more information about this error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)