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

Confusing "type parameter" in error message. #47319

Closed
kevincox opened this issue Jan 10, 2018 · 18 comments · Fixed by #66014
Closed

Confusing "type parameter" in error message. #47319

kevincox opened this issue Jan 10, 2018 · 18 comments · Fixed by #66014
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kevincox
Copy link
Contributor

kevincox commented Jan 10, 2018

I have thought this is odd for a while, however after teaching a Rust introduction class I found numerous attendees stumbling on this weird error for a simple and common case.

error[E0308]: mismatched types
   --> src/codelab.rs:100:5
    |
100 |   tail.val
    | 	^^^^^^^^ expected enum `std::option::Option`, found type parameter
    |
    = note: expected type `std::option::Option<T>`
    = note:    found type `T`

The "found type parameter" part is confusing, as I (and most students) interpret this as some sort of weird syntax-like error. For example it feels similar to the "expected {, found ;" you get from syntax errors.

I think that simply adding `T` after the message would make this much more understandable.

error[E0308]: mismatched types
   --> src/codelab.rs:100:5
    |
100 |   tail.val
    | 	^^^^^^^^ expected enum `std::option::Option`, found type parameter `T`
    |
    = note: expected type `std::option::Option<T>`
    = note:    found type `T`

Possibly more controversial is dropping "parameter" or "type parameter" I don't think they add much value to the error message.

This issue has been assigned to @dkadashev via this comment.

@Mark-Simulacrum Mark-Simulacrum added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-diagnostics Area: Messages for errors, warnings, and lints labels Jan 10, 2018
@Mark-Simulacrum
Copy link
Member

Well, I think rather we can say something like "generic T" or similar -- we probably don't want just "T" since there could be a type with that name in scope as well.

Likely a rather simple fix, but I wasn't able to quickly find where this diagnostic gets emitted.

@estebank
Copy link
Contributor

estebank commented Jan 10, 2018

I would go further and say that the full output should be:

error[E0308]: mismatched types
   --> src/codelab.rs:100:5
    |
xx  |  fn foo<T>(...) => T {
    |         - this type parameter
100 |   tail.val
    | 	^^^^^^^^ expected enum `std::option::Option`, found type parameter `T`
    |
    = note: expected type `std::option::Option<T>`
    = note:    found type `T`

I believe you could modify note_and_explain_type_err in order to check if the error is of TypeError::Sorts(ty.sty: TypeVariants::Param(param), _) | TypeError::Sorts(_, ty.sty: TypeVariants::Param(param)) (but not TypeError::Sorts(ty.sty: TypeVariants::Param(param), ty.sty: TypeVariants::Param(param)). The hard part is to either look at the enclosing scope (meaning passing some DefId into the mentioned method) or expanding ParamTy to hold its Span in order to be able to show it in errors (I think there are other cases where it'd be needed to have it, so I'd be inclined to go down that route).

As for the main span's label, these are the lines where the "expected {}, found {}" is being produced. You could either enclose it with a check for an expected/found type parameter, or (better yet) modify sort_string to include the type argument's name.

@estebank estebank added the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Jan 10, 2018
@kevincox
Copy link
Contributor Author

I would go further and say that the full output should be: ... ^ this type parameter

This seems a little unnecessary to me as the names are often obvious enough. But I'm not opposed to this.

@gaurikholkar-zz
Copy link

Anyone working on this?

@estebank
Copy link
Contributor

This seems a little unnecessary to me as the names are often obvious enough.

Usually (except in the case of nested impl/fn blocks), but adding that makes it so that if you're using rustc directly, you have all the necessary context available before you go back to your editor, and if you're using an editor that supports the RLS, the editor will highlight the proper span. Also consider that error messages have to be understandable to both people very acquainted with the language as well as to people who have just started programming. When in doubt, I lean towards the side of over explaining.

Furthermore, consider the current snippet: we don't know wether this was in an impl, a struct or an fn. Having that information available would make it easier to give more targeted explanations on stackoverflow, for example.

Anyone working on this?

Feel free to take it on!

@jdahlstrom
Copy link

Another pretty confusing instance of this in #47499, only with two type parameters.

@kevincox
Copy link
Contributor Author

Has anyone taken ownership? I'd be willing to start a patch this weekend if no one is working on it.

@estebank
Copy link
Contributor

I believe @gaurikholkar wanted to take it up, but I don't know if she's already started.

@gaurikholkar-zz
Copy link

I've strated working on it @kevincox

@gaurikholkar-zz
Copy link

Made the following changes to my locally and WIP.

@gaurikholkar-zz
Copy link

I guess we go with the DefId then @estebank ?

@estebank
Copy link
Contributor

As things stand, I believe that will be the best bet. Could you try and see how hard it would be to add a HashMap<DefId, Span> for param ids to, I'm guessing tcx?

@steveklabnik
Copy link
Member

Triage: @gaurikholkar , did you ever finish this work?

@dkadashev
Copy link
Contributor

Hi @estebank, if no one is working on this (which seems to be the case) then I'd like to pick this up (as a first contribution to the compiler) if that's OK.

I think it makes sense to make two separate PRs, the first one for the "modify sort_string to include the type argument's name" part and the second for the span part, since these changes are fairly unrelated to each other, and the former one is trivial and seems to be helpful on its own. Or it can be just separate commits in a single PR if that is preferable. Please let me know what's the best way here.

Also does the recommendation from #47319 (comment) still stand or is there a better way now, given the amount of time passed?

@estebank
Copy link
Contributor

@dkadashev I believe that is indeed the case.

@dkadashev
Copy link
Contributor

Status update: after playing with this for a while and hitting pretty much the same problems described in #47574 I think I finally have a fix (nice and small). Preparing a PR now (will take some time though - clean builds, etc.)

@dkadashev
Copy link
Contributor

@rustbot claim

@rustbot rustbot self-assigned this Oct 31, 2019
@dkadashev
Copy link
Contributor

Some examples.

Two parameters case that was covered by #47499:

3 | fn foo<T, U>(t: T, u: U) {
  |        -  - found type parameter
  |        |
  |        expected type parameter
4 |     bar(t, u);
  |            ^ expected type parameter `T`, found type parameter `U`

One parameter case from the top of this ticket:

9  | fn foo1<T>(t: T) {
   |         - this type parameter
10 |     bar1(t);
   |          ^
   |          |
   |          expected enum `std::option::Option`, found type parameter `T`
   |          help: try using a variant of the expected enum: `Some(t)`

Same for impl - including type params on different levels:

17 | impl<T> S<T> {
   |      - expected type parameter
...
22 |     fn foo3<U>(self, u: U) {
   |             - found type parameter
23 |         bar(self.t, u);
   |                     ^ expected type parameter `T`, found type parameter `U`
17 | impl<T> S<T> {
   |      - this type parameter
18 |     fn foo2(self) {
19 |         bar1(self.t);
   |              ^^^^^^
   |              |
   |              expected enum `std::option::Option`, found type parameter `T`
   |              help: try using a variant of the expected enum: `Some(self.t)`

@estebank estebank added D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 31, 2019
dkadashev added a commit to dkadashev/rust that referenced this issue Nov 2, 2019
Part of rust-lang#47319.

This just adds type parameter name to type mismatch error message, so
e.g. the following:

```
expected enum `std::option::Option`, found type parameter
```

becomes

```
expected enum `std::option::Option`, found type parameter `T`
```
Centril added a commit to Centril/rust that referenced this issue Nov 5, 2019
…tion, r=estebank

Show type parameter name and definition in type mismatch error messages

Fixes rust-lang#47319

r? estebank
Centril added a commit to Centril/rust that referenced this issue Nov 6, 2019
…tion, r=estebank

Show type parameter name and definition in type mismatch error messages

Fixes rust-lang#47319

r? estebank
@bors bors closed this as completed in 036f182 Nov 6, 2019
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 C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. 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.

8 participants