Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving type inference / annotation explicitness diagnostic #105510

Closed
jaybosamiya opened this issue Dec 9, 2022 · 0 comments · Fixed by #105523
Closed

Improving type inference / annotation explicitness diagnostic #105510

jaybosamiya opened this issue Dec 9, 2022 · 0 comments · Fixed by #105523
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jaybosamiya
Copy link

A minimized example, derived from a chain of changes that a friend (who has just begun learning Rust) did.

Starting from this code (Playground link):

fn main() {
    let x = "".chars().collect();
}

The current output is:

error[E0282]: type annotations needed
 --> src/main.rs:2:9
  |
2 |     let x = "".chars().collect();
  |         ^
  |
help: consider giving `x` an explicit type
  |
2 |     let x: _ = "".chars().collect();
  |          +++

Now someone more familiar with Rust wouldn't just blindly add a : _ (since it doesn't lead to telling Rust anything new here, just would move the problem), but this friend is new to Rust, and has often found suggestions in the "help:" section to immediately provide fixes, so they add the : _, making the code into this (Playground link):

fn main() {
    let x: _ = "".chars().collect();
}

The current output for this is:

error[E0282]: type annotations needed
 --> src/main.rs:2:27
  |
2 |     let x: _ = "".chars().collect();
  |                           ^^^^^^^ cannot infer type of the type parameter `B` declared on the associated function `collect`
  |
help: consider specifying the generic argument
  |
2 |     let x: _ = "".chars().collect::<B>();
  |                                  +++++

Since they aren't sure what this B is doing, but they realize that that it is a type parameter, they decide "oh, Rust can infer types for me, I'll just let it infer it", and decide to add the turbofish with _, i.e., ::<_>, making the code into this (Playground link):

fn main() {
    let x: _ = "".chars().collect::<_>();
}

Again any seasoned Rust programmer would instantly recognize that this is unhelpful, but nonetheless, this leads to the following output:

error[E0282]: type annotations needed
 --> src/main.rs:2:27
  |
2 |     let x: _ = "".chars().collect::<_>();
  |                           ^^^^^^^ cannot infer type of the type parameter `B` declared on the associated function `collect`
  |
help: consider specifying the generic argument
  |
2 |     let x: _ = "".chars().collect::<_>();
  |                                  ~~~~~

At this point, we've reached a fixed-point, and the error message is copied over to chat-message-platform-of-choice, with an "excuse me what rust" message:
screenshot of text stating 'excuse me what rust' where the 'rust' is highlighted as an alert

I help them understand what happened, and they fix the issue, and go on their way. However, this now seems like a point where diagnostics could be improved. (Btw, the original issue happened nested inside an iterator chain inside another iterator chain, and there was a type error along the way too, so lots more issues there; I've distilled it down to the above story just to remove all irrelevant details; also, while not in the above story, if instead of beginning with the : _, someone added the turbofish first (i.e., let x = "".chars().collect::<_>();), then too one hits the final fixed-point case)


What could be improved:

  1. If something is explicitly marked as "to be inferred" via the _, maybe something like "cannot infer type of the type parameter B (here, _) declared on the associated function collect" or similar. Probably someone can come up with a better way to write that though, but there should be something that connects the B.
  2. If both "sides" are marked to be inferred (in this case, type of x and type parameter in the turbofish), and making any one of them explicit would be sufficient, having an error message that says this might help.
  3. Adding a diagnostic that specifically points out such annotations in general would also potentially help. In particular, I don't see any situation where (verbatim) ::<_> is useful; except maybe in this animation. Having a diagnostic that tells users would probably be good. Similarly for (verbatim) : _. (I hope what I am saying here makes sense: I'm saying, as an example, ::<Vec<_>> is fine, but ::<_> is not).
  4. (Not 100% the goal of the above story, but still) collect could have a special diagnostic help message that mentions containers, rather than the B which can be confusing to new users.
@jaybosamiya jaybosamiya added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 9, 2022
@bors bors closed this as completed in e5fde96 Dec 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant