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

Better error message when trying to write default impls #49372

Merged

Conversation

Phlosioneer
Copy link
Contributor

@Phlosioneer Phlosioneer commented Mar 26, 2018

Previously, if you tried to write this (using the specialization
feature flag):

default impl PartialEq {
...
}

The compiler would give you the mysterious warning "inherent impls
cannot be default". What it really means is that you're trying to
write an impl for a Structure or Trait Object, and that cannot
be "default". However, one of the ways to encounter this error
(as shown by the above example) is when you forget to write "for
MyType".

This PR adds a help message that reads "maybe missing a for
keyword?" This is useful, actionable advice that will help any user
identify their mistake, and doesn't get in the way or mislead any
user that really meant to use the "default" keyword for this weird
purpose. In particular, this help message will be useful for any
users who don't know the "inherent impl" terminology, and/or users
who forget that inherent impls CAN be written for traits (they apply
to the trait objects). Both of these are somewhat confusing, seldom-
used concepts; a one-line error message without any error number for
longer explanation is NOT the place to introduce these ideas.

I wasn't quite sure what grammar / wording to use. I'm open to suggestions. CC @rust-lang/docs (I hope I'm doing that notation right)

(Apparently not. :( )

Previously, if you tried to write this (using the specialization
feature flag):

default impl PartialEq<MyType> {
...
}

The compiler would give you the mysterious warning "inherent impls
cannot be default". What it really means is that you're trying to
write an impl for a Structure or *Trait Object*, and that cannot
be "default". However, one of the ways to encounter this error
(as shown by the above example) is when you forget to write "for
MyType".

This PR adds a help message that reads "maybe missing a `for`
keyword?" This is useful, actionable advice that will help any user
identify their mistake, and doesn't get in the way or mislead any
user that really meant to use the "default" keyword for this weird
purpose. In particular, this help message will be useful for any
users who don't know the "inherent impl" terminology, and/or users
who forget that inherent impls CAN be written for traits (they apply
to the trait objects). Both of these are somewhat confusing, seldom-
used concepts; a one-line error message without any error number for
longer explanation is NOT the place to introduce these ideas.
@pietroalbini pietroalbini added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 26, 2018
@pietroalbini
Copy link
Member

Highfive failed to pick a reviewer for this PR.

r? @estebank

Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

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

I would prefer a suggestion if it could be provided, with text close to

help: if you meant to write an `impl` for `PartialEq`, use the `for` keyword: `default impl for PartialEq`

(I hope I'm doing that notation right)

Only members of the org can CC teams.

CC @rust-lang/docs

I'm gonna be offline for two weeks. Apologies in advance for the unresponsiveness.

self.err_handler().span_err(item.span, "inherent impls cannot be default");
self.err_handler()
.struct_span_err(item.span, "inherent impls cannot be default")
.help("maybe a missing `for` keyword?");
Copy link
Contributor

Choose a reason for hiding this comment

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

This is creating a DiagnosticBuilder but never has .emit() called on it, which causes an Internal Compiler Error in test compile-fail/specialization/defaultimpl/validation.rs.

Assign the result of the struct_span_err to a mutable variable err and then err.help(...) and err.emit().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, okay. Sorry, I'm not very familiar with internals. And there's no rush for feedback, thanks for the warning.

@petrochenkov
Copy link
Contributor

one of the ways to encounter this error
(as shown by the above example) is when you forget to write "for
MyType".

And another way is to actually write default impl MyStruct<T> { ... } in attempt to use specialization on inherent methods.
You can't recommend for without checking that X in default impl X { ... } is actually a trait.

@Phlosioneer
Copy link
Contributor Author

True... I don't know that we can do that here, though. Isn't this AST validation, before we've resolved trait names and the like?

Also, I don't know how to do that; I'm not very familiar with the rustc internals. Do you happen to know how to do that, or someplace I can start looking?

@shepmaster
Copy link
Member

Since @estebank is out, randomly assigning to...

r? @nagisa

@rust-highfive rust-highfive assigned nagisa and unassigned estebank Apr 7, 2018
@nagisa
Copy link
Member

nagisa commented Apr 8, 2018

Rather than trying to be helpful here and phrasing your suggestion as a question, I’d recommend using a note and informing the user that only trait implementations may be annotated with default or some similar wording.

@pietroalbini pietroalbini added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 16, 2018
@pietroalbini
Copy link
Member

Ping from triage @Phlosioneer! The reviewer left some comments, could you address them?

@pietroalbini pietroalbini added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 23, 2018
@pietroalbini
Copy link
Member

Ping from triage @nagisa! The author addressed your concerns, could you review this again?

@nagisa
Copy link
Member

nagisa commented Apr 23, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Apr 23, 2018

📌 Commit c61e641 has been approved by nagisa

@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 Apr 23, 2018
@bors
Copy link
Contributor

bors commented Apr 23, 2018

⌛ Testing commit c61e641 with merge 4640615...

bors added a commit that referenced this pull request Apr 23, 2018
…e, r=nagisa

Better error message when trying to write default impls

Previously, if you tried to write this (using the specialization
feature flag):

default impl PartialEq<MyType> {
...
}

The compiler would give you the mysterious warning "inherent impls
cannot be default". What it really means is that you're trying to
write an impl for a Structure or *Trait Object*, and that cannot
be "default". However, one of the ways to encounter this error
(as shown by the above example) is when you forget to write "for
MyType".

This PR adds a help message that reads "maybe missing a `for`
keyword?" This is useful, actionable advice that will help any user
identify their mistake, and doesn't get in the way or mislead any
user that really meant to use the "default" keyword for this weird
purpose. In particular, this help message will be useful for any
users who don't know the "inherent impl" terminology, and/or users
who forget that inherent impls CAN be written for traits (they apply
to the trait objects). Both of these are somewhat confusing, seldom-
used concepts; a one-line error message without any error number for
longer explanation is NOT the place to introduce these ideas.

I wasn't quite sure what grammar / wording to use. I'm open to suggestions. CC @rust-lang/docs (I hope I'm doing that notation right)

(Apparently not. :( )
@bors
Copy link
Contributor

bors commented Apr 23, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nagisa
Pushing 4640615 to master...

@bors bors merged commit c61e641 into rust-lang:master Apr 23, 2018
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants