-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Show span for trait that doesn't implement Copy #37493
Show span for trait that doesn't implement Copy #37493
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Aatch (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
|
9a416ad
to
9575724
Compare
Cool. Yeah, I like this, I think. Does it work for things that aren't enum variants also? Looking at the code, I was a little confused: pub fn span_if_local(&self, id: DefId) -> Option<Span> {
self.as_local_node_id(id).map(|id| self.span(id))
}
pub fn span_if_local_opt(&self, id: DefId) -> Option<Span> {
self.as_local_node_id(id).and_then(|id| self.opt_span(id))
} Do we need the new function you're adding? Seem similar |
@jonathandturner during my testing if I found cases where an
It should work for structs too. I can add an unittest for that case if you want. |
b4a9ca1
to
fdc8777
Compare
@jonathandturner left only |
this type"); | ||
err.span_label(span, &format!("field `{}` does not implement `Copy`", name)); | ||
if let Some(def_span) = tcx.map.span_if_local(did) { | ||
err.span_label(def_span, &format!("`{}` defined here", name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see tests for this "defined here" branch. There's a test for variant "defined here" case, but not for fields. Can you add one if there aren't?
Although I think this improvement is fine as is, some thoughts about this example:
It's peculiar that the subject of the error, the type "Test", is mentioned in an extremely non-prominent way. The main error text, "may not be implemented for this type", makes it sound like a type is the most important thing in this error, but the two snippets printed are about variants, and don't mention the type. Underlining When the variant is defined before the impl, as in this example, the first snippet is no longer pointing to the subject of the error, that is, Considering the information at hand I might find something like the following more illuminating:
then maybe even "because I'm not sure how correct it is to say that a variant implements a trait, since variants are not types. |
Oh, here's another try:
This makes it about the variant, assuming that the solution is to make I don't know if that's true or not though. Just some ideas. The more important case anyway is the one where |
@brson changed the output to:
How does that look?
There's already a non ui test for it |
I'd say this is probably getting close enough. The one question I had looking at it comparing the two was here:
In the E0205 case we show where the problem is, but here you have to go find where |
I've been trying to get the field |
27ef67e
to
df8a29a
Compare
So I've found that struct items are never part of the Map. I've made it so that they're added, pointing to the struct's Node, as I haven't been able to find a clean way to add an
I am intrigued as to the rationale for variants to be indexed, while struct fields aren't. |
df8a29a
to
c19113b
Compare
} else { | ||
// This should be replaced with `visit_struct_field` once there's a Node | ||
// for struct fields. In the meantime, register the parent node to have | ||
// something to point to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, this. I think I've added nodes for fields in at least two branches already.
Do you mind waiting for #37676? It could land in less than a week and has the correct fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't seen that PR. That's quite a refactor! I have no problem waiting for it.
c19113b
to
9c8f7fa
Compare
@jonathandturner, @eddyb: after #37676 landing, now both cases point to the element (variant/field) that doesn't implement
|
@estebank - interesting. so if that's true, does that mean the main issue here got fixed? |
@jonathandturner #37676 added spans for struct fields to the map, which allows me to point at the correct field in this error. The current output doesn't point at the field or variant that doesn't implement
|
Oh I got it! That's awesome then. Ready for review? |
Yeah! 👍 |
2b35c63
to
7ba99a4
Compare
name, | ||
self_type)); | ||
&format!("field `{}` doesn't implement `Copy`", | ||
name)); | ||
if let Some(def_span) = tcx.map.span_if_local(did) { | ||
err.span_label(def_span, &"this field doesn't implement `Copy`"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking something more like:
if let Some(def_span) = tcx.map.span_if_local(did) {
err.span_label(def_span, &"this field doesn't implement `Copy`");
err.span_label(span, &format!("field `{}` doesn't implement `Copy`", name));
} else {
err.span_label(span,
&format!("field `{}` in struct `{}` doesn't implement `Copy`",
name,
self_type));
}
That way, in the case we don't have the def_span available, we can still give them a little more hint as to where it's coming from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonathandturner We should talk about a transition plan: ideally, span_if_local
wouldn't exist after #37954, as every DefId
has an associated Span
.
The problem is that there's no source available and there's a few ways in which we could approach this (including embedding the full source in metadata).
In any case, long-term I'd like to not have code that branches out like this, but rather generate "field bar of struct Foo" from just its DefId
, and point to its span if local, unless we can somehow show the source itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay, got it. We can experiment with that later, but sounds like that'll affect more than just this PR. I don't want to hold this one up while we figure out the bigger picture.
@bors r+ |
📌 Commit 7ba99a4 has been approved by |
⌛ Testing commit 7ba99a4 with merge c75925e... |
💔 Test failed - auto-win-gnu-32-opt-rustbuild |
7ba99a4
to
44edb55
Compare
Had to rebase against master to fix error. Tests have completed, I'll be needing a new r+, @jonathandturner. |
@bors r+ |
📌 Commit 44edb55 has been approved by |
⌛ Testing commit 44edb55 with merge a1b0040... |
💔 Test failed - auto-win-gnu-32-opt-rustbuild |
Failure seems legit:
|
Just took a look at it and this was caused because the ordering of messages is not consistent across platforms. Is it ok if I split this test case into two separate files while I work on ordering the output of errors in a separate PR? |
83ffdbc
to
a8e24a2
Compare
@estebank - are you saying that a single test might give multiple results non-deterministically? If that's the case, that sounds bad (and something we should definitely fix) |
@jonathandturner The error was that the order of the errors was swapped. Given it failed only in win32 that made me think that the order the errors are emitted is different in different platforms (even though that makes little sense). I think more likely there was a change in the emit order between the time it got tested by travis and the time it go tested by bors. |
☔ The latest upstream changes (presumably #38357) made this pull request unmergeable. Please resolve the merge conflicts. |
a8e24a2
to
8c640fe
Compare
☔ The latest upstream changes (presumably #38499) made this pull request unmergeable. Please resolve the merge conflicts. |
8c640fe
to
8d5c21a
Compare
☔ The latest upstream changes (presumably #38449) made this pull request unmergeable. Please resolve the merge conflicts. |
Change error message to ```nocode error[E0205]: the trait `Copy` may not be implemented for type `Foo` --> $DIR/issue-19950.rs:17:6 | 14 | MyVariant(NoCopy) | ----------------- this variant doesn't implement `Copy` ... 17 | impl Copy for Foo {} | ^^^^ variant `Foo::MyVariant` doesn't implement `Copy` error[E0204]: the trait `Copy` may not be implemented for type `Bar` --> $DIR/issue-19950.rs:23:1 | 20 | item: NoCopy, | ------------ this field doesn't implement `Copy` ... 23 | impl Copy for Bar {} | ^^^^^^^^^^^^^^^^^^^^ field `item` in struct `Bar` doesn't implement `Copy` ```
8d5c21a
to
d9d75b5
Compare
☔ The latest upstream changes (presumably #38152) made this pull request unmergeable. Please resolve the merge conflicts. |
Superseded by #38152. Sorry, didn't notice this PR was open. Thanks for the PR! |
Point at span for trait that doesn't implement
Copy
.Given the following code:
show the following output:
Re: #19950.