Skip to content

Commit

Permalink
Suggest new type param on single char ident
Browse files Browse the repository at this point in the history
Suggest new type parameter on single char uppercase ident even if it
doesn't appear in a field's type parameter.

Address comment in #72641.
  • Loading branch information
estebank committed Jun 17, 2020
1 parent 4606168 commit af45d8a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 15 deletions.
41 changes: 33 additions & 8 deletions src/librustc_resolve/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,20 +919,45 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
&self,
path: &[Segment],
) -> Option<(Span, &'static str, String, Applicability)> {
let ident = match path {
[segment] if !segment.has_args => segment.ident,
let (ident, span) = match path {
[segment] if !segment.has_args => (segment.ident.to_string(), segment.ident.span),
_ => return None,
};
match (
self.diagnostic_metadata.current_item,
self.diagnostic_metadata.currently_processing_generics,
) {
(Some(Item { kind: ItemKind::Fn(..), ident, .. }), true) if ident.name == sym::main => {
let mut iter = ident.chars().map(|c| c.is_uppercase());
let single_uppercase_char =
matches!(iter.next(), Some(true)) && matches!(iter.next(), None);
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 => {
// Ignore `fn main()` as we don't want to suggest `fn main<T>()`
}
(Some(Item { kind, .. }), true) => {
(
Some(Item {
kind:
kind @ ItemKind::Fn(..)
| kind @ ItemKind::Enum(..)
| kind @ ItemKind::Struct(..)
| kind @ ItemKind::Union(..),
..
}),
true,
)
| (Some(Item { kind, .. }), false) => {
// Likely missing type parameter.
if let Some(generics) = kind.generics() {
if span.overlaps(generics.span) {
// Avoid the following:
// error[E0405]: cannot find trait `A` in this scope
// --> $DIR/typo-suggestion-named-underscore.rs:CC:LL
// |
// L | fn foo<T: A>(x: T) {} // Shouldn't suggest underscore
// | ^- help: you might be missing a type parameter: `, A`
// | |
// | not found in this scope
return None;
}
let msg = "you might be missing a type parameter";
let (span, sugg) = if let [.., param] = &generics.params[..] {
let span = if let [.., bound] = &param.bounds[..] {
Expand Down
11 changes: 10 additions & 1 deletion src/test/ui/associated-types/associated-types-eq-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ error[E0412]: cannot find type `A` in this scope
LL | fn foo2<I: Foo>(x: I) {
| - similarly named type parameter `I` defined here
LL | let _: A = x.boo();
| ^ help: a type parameter with a similar name exists: `I`
| ^
|
help: a type parameter with a similar name exists
|
LL | let _: I = x.boo();
| ^
help: you might be missing a type parameter
|
LL | fn foo2<I: Foo, A>(x: I) {
| ^^^

error: aborting due to previous error

Expand Down
8 changes: 6 additions & 2 deletions src/test/ui/suggestions/type-not-found-in-adt-field.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
struct S {
m: Vec<Hashmap<String, ()>>, //~ ERROR cannot find type `Hashmap` in this scope
struct Struct {
m: Vec<Someunknownname<String, ()>>, //~ ERROR cannot find type `Someunknownname` in this scope
//~^ NOTE not found in this scope
}
struct OtherStruct { //~ HELP you might be missing a type parameter
m: K, //~ ERROR cannot find type `K` in this scope
//~^ NOTE not found in this scope
}
fn main() {}
16 changes: 12 additions & 4 deletions src/test/ui/suggestions/type-not-found-in-adt-field.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
error[E0412]: cannot find type `Hashmap` in this scope
error[E0412]: cannot find type `Someunknownname` in this scope
--> $DIR/type-not-found-in-adt-field.rs:2:12
|
LL | m: Vec<Hashmap<String, ()>>,
| ^^^^^^^ not found in this scope
LL | m: Vec<Someunknownname<String, ()>>,
| ^^^^^^^^^^^^^^^ not found in this scope

error: aborting due to previous error
error[E0412]: cannot find type `K` in this scope
--> $DIR/type-not-found-in-adt-field.rs:6:8
|
LL | struct OtherStruct {
| - help: you might be missing a type parameter: `<K>`
LL | m: K,
| ^ not found in this scope

error: aborting due to 2 previous errors

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

0 comments on commit af45d8a

Please sign in to comment.