Skip to content

Conversation

kornelski
Copy link
Contributor

@kornelski kornelski commented Mar 17, 2024

The compiler may suggest unusable generic type names for missing generic arguments in an expression context:

fn main() {
    (0..1).collect::<Vec>()
}

help: add missing generic argument

 (0..1).collect::<Vec<T>>()

but T is not a valid name in this context, and this suggestion won't compile.

I've changed it to use _ inside method calls (turbofish), so it will suggest (0..1).collect::<Vec<_>>() which may compile.

It's possible that the suggested _ will be ambiguous, but there is very extensive E0283 that will help resolve that, which is more helpful than a basic "cannot find type T in this scope" users would get otherwise.

Out of caution to limit scope of the change I've limited it to just turbofish, but I suspect _ could be the better choice in more cases. Perhaps in all expressions?

@rustbot
Copy link
Collaborator

rustbot commented Mar 17, 2024

r? @spastorino

rustbot has assigned @spastorino.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 17, 2024
Comment on lines +438 to +452
let is_in_a_method_call = self
.tcx
.hir()
.parent_iter(self.path_segment.hir_id)
.skip(1)
.find_map(|(_, node)| match node {
hir::Node::Expr(expr) => Some(expr),
_ => None,
})
.is_some_and(|expr| {
matches!(
expr.kind,
hir::ExprKind::MethodCall(hir::PathSegment { args: Some(_), .. }, ..)
)
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this going to be true when we're inside a nested item? You should probably limit this search somehow so it doesn't trigger for like

fn hello() {
  x.foo({
    fn bar() {
        let x: Vec;
    }
  });

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find_map picks only the first expression, so it stops at the block around fn. I don't think it's possible to have an item directly as an argument.

I've considered checking whether MethodCall's args contain self.path_segment, but that requires digging a few layers deep, and the code for it is pretty involved.

BTW, let x: Vec<T> is not a great suggestion, and let x: Vec<_> would have been better. I'm wondering whether it should always use _ on non-items inside function bodies, and limit suggestions of parameter names to items where _ is not allowed.

@spastorino
Copy link
Member

spastorino commented Mar 22, 2024

Seems good to me but r? @compiler-errors as they've already made the initial review.

@compiler-errors
Copy link
Member

@bors r=spastorino,compiler-errors

@bors
Copy link
Collaborator

bors commented Mar 22, 2024

📌 Commit 3bbbe3c has been approved by spastorino,compiler-errors

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 22, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 22, 2024
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#114009 (compiler: allow transmute of ZST arrays with generics)
 - rust-lang#122195 (Note that the caller chooses a type for type param)
 - rust-lang#122651 (Suggest `_` for missing generic arguments in turbofish)
 - rust-lang#122784 (Add `tag_for_variant` query)
 - rust-lang#122839 (Split out `PredicatePolarity` from `ImplPolarity`)
 - rust-lang#122873 (Merge my contributor emails into one using mailmap)
 - rust-lang#122885 (Adjust better spastorino membership to triagebot's adhoc_groups)
 - rust-lang#122888 (add a couple more tests)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 22, 2024
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#114009 (compiler: allow transmute of ZST arrays with generics)
 - rust-lang#122195 (Note that the caller chooses a type for type param)
 - rust-lang#122651 (Suggest `_` for missing generic arguments in turbofish)
 - rust-lang#122784 (Add `tag_for_variant` query)
 - rust-lang#122839 (Split out `PredicatePolarity` from `ImplPolarity`)
 - rust-lang#122873 (Merge my contributor emails into one using mailmap)
 - rust-lang#122885 (Adjust better spastorino membership to triagebot's adhoc_groups)
 - rust-lang#122888 (add a couple more tests)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 4e59457 into rust-lang:master Mar 23, 2024
@rustbot rustbot added this to the 1.79.0 milestone Mar 23, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Mar 23, 2024
Rollup merge of rust-lang#122651 - kornelski:flat-turbofish, r=spastorino,compiler-errors

Suggest `_` for missing generic arguments in turbofish

The compiler may suggest unusable generic type names for missing generic arguments in an expression context:

```rust
fn main() {
    (0..1).collect::<Vec>()
}
```

> help: add missing generic argument
>
>      (0..1).collect::<Vec<T>>()

but `T` is not a valid name in this context, and this suggestion won't compile.

I've changed it to use `_` inside method calls (turbofish), so it will suggest `(0..1).collect::<Vec<_>>()` which _may_ compile.

It's possible that the suggested `_` will be ambiguous, but there is very extensive E0283 that will help resolve that, which is more helpful than a basic "cannot find type `T` in this scope" users would get otherwise.

Out of caution to limit scope of the change I've limited it to just turbofish, but I suspect `_` could be the better choice in more cases. Perhaps in all expressions?
flip1995 pushed a commit to flip1995/rust that referenced this pull request Apr 4, 2024
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#114009 (compiler: allow transmute of ZST arrays with generics)
 - rust-lang#122195 (Note that the caller chooses a type for type param)
 - rust-lang#122651 (Suggest `_` for missing generic arguments in turbofish)
 - rust-lang#122784 (Add `tag_for_variant` query)
 - rust-lang#122839 (Split out `PredicatePolarity` from `ImplPolarity`)
 - rust-lang#122873 (Merge my contributor emails into one using mailmap)
 - rust-lang#122885 (Adjust better spastorino membership to triagebot's adhoc_groups)
 - rust-lang#122888 (add a couple more tests)

r? `@ghost`
`@rustbot` modify labels: rollup
@kornelski kornelski deleted the flat-turbofish branch August 14, 2024 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants