-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Don't display default generic parameters in diagnostics that compare types #52244
Conversation
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
src/test/ui/type-mismatch.stderr
Outdated
@@ -194,16 +194,16 @@ LL | want::<Foo<foo, B>>(f); //~ ERROR mismatched types | |||
| ^ expected struct `B`, found struct `A` |
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.
Note this error becomes awkward:
^ expected struct `B`, found struct `A`
= note: expected type `Foo<_, B>`
found type `Foo<_, A>`
found type `Foo<_>`
Maybe this particular case should display the parameters.
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.
You should probably create a new method similar to strip_generic_default_params
that checks wether the default associated type has been changed, and if it has, don't call strip_generic_default_params
. Does that make sense?
This is part of the reason we haven't unified ppaux
and this: this code is conditional on the state of two types with very specific interactions.
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.
Turns out addressing the awkwardness made the change simpler. I added more tests, too.
I'll note that I'm also not particularly proud of the code duplication from rust/src/librustc/util/ppaux.rs Lines 312 to 334 in acf50b7
(I don't know in what case generics.parent can be Some()) |
@glandium Regarding your last comment, this is a complete hack at the moment, and we need to figure out a good design to merge the code you're modifying and |
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.
Otherwise, it looks sound to me.
src/test/ui/type-mismatch.stderr
Outdated
@@ -194,16 +194,16 @@ LL | want::<Foo<foo, B>>(f); //~ ERROR mismatched types | |||
| ^ expected struct `B`, found struct `A` |
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.
You should probably create a new method similar to strip_generic_default_params
that checks wether the default associated type has been changed, and if it has, don't call strip_generic_default_params
. Does that make sense?
This is part of the reason we haven't unified ppaux
and this: this code is conditional on the state of two types with very specific interactions.
They highlight how types are displayed in those cases, and will show how the current output is altered by the next patch.
@bors r+ rollup |
📌 Commit b5c2b79 has been approved by |
| ^ expected struct `bar`, found struct `foo` | ||
| | ||
= note: expected type `Foo<bar, _, B>` | ||
found type `Foo<foo, _, A>` |
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.
Just out of curiosity, are bar
, foo
, B
and A
highlighted in the output here? I would think yes, but want to confirm (regardless, this PR is going in, I'm asking just to see if I have to file a ticket to add that).
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.
Yes, they are. It would be great if the ui tests actually tested for that too. It would become more apparent that there's some inconsistency for e.g. usize
/Foo<usize>
where everything is highlighted as opposed to foo
/Foo<foo>
where foo
is not highlighted, which is because usize is not an Adt and doesn't fall in the same code path as foo.
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 think that the latter is not because of that but rather because foo
is detected as the first type argument to Foo
, which means that the think to highlight is only Foo
, indirectly telling you "you need to wrap this with a Foo
!". It's the same as when you have an Option<Foo>
and a Result<Foo, _>
was expected, Foo
doesn't get highlighted.
It would be great if the ui tests actually tested for that too.
It would, but it probably would be a pain to look at :-/ The current situation is good enough™ that we haven't pushed to change it yet.
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.
No, really, it's only because foo
is an Adt, and usize
isn't. The comparison between foo
and Foo<foo>
hits this pattern:
(&ty::TyAdt(def1, sub1), &ty::TyAdt(def2, sub2)) => { |
while the comparison between usize
and Foo<usize>
hits this one:
_ => { |
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.
Oh! You're absolutely right. I though I had expanded a few more branches to account for this case before, but now looking at the code in master I see that I must have never submitted that PR.
Don't display default generic parameters in diagnostics that compare types In errors like: ``` expected type: `RawVec<foo, Global>` found type: `foo` ``` `RawVec` being defined as `RawVec<T, A: Alloc = Global>`, the error is better written as ``` expected type: `RawVec<foo>` found type: `foo` ``` In fact, that is already what happens when `foo` is not an ADT, because in that case, the diagnostic handler doesn't try to highlight something, and just uses the `Display` trait instead of its own logic. e.g. ``` expected type: `RawVec<usize>` found type: `usize` ```
Rollup of 16 pull requests Successful merges: - #51962 (Provide llvm-strip in llvm-tools component) - #52003 (Implement `Option::replace` in the core library) - #52156 (Update std::ascii::ASCIIExt deprecation notes) - #52242 (NLL: Suggest `ref mut` and `&mut self`) - #52244 (Don't display default generic parameters in diagnostics that compare types) - #52290 (Deny bare trait objects in src/librustc_save_analysis) - #52293 (Deny bare trait objects in librustc_typeck) - #52299 (Deny bare trait objects in src/libserialize) - #52300 (Deny bare trait objects in librustc_target and libtest) - #52302 (Deny bare trait objects in the rest of rust) - #52310 (Backport 1.27.1 release notes to master) - #52314 (Fix ICE when using a pointer cast as array size) - #52315 (Resolve FIXME(#27942)) - #52316 (task: remove wrong comments about non-existent LocalWake trait) - #52322 (Update llvm-rebuild-trigger in light of LLVM 7 upgrade) - #52332 (dead-code lint: say "constructed", "called" for structs, functions) Failed merges: r? @ghost
Don't display default generic parameters in diagnostics that compare types In errors like: ``` expected type: `RawVec<foo, Global>` found type: `foo` ``` `RawVec` being defined as `RawVec<T, A: Alloc = Global>`, the error is better written as ``` expected type: `RawVec<foo>` found type: `foo` ``` In fact, that is already what happens when `foo` is not an ADT, because in that case, the diagnostic handler doesn't try to highlight something, and just uses the `Display` trait instead of its own logic. e.g. ``` expected type: `RawVec<usize>` found type: `usize` ```
☀️ Test successful - status-appveyor, status-travis |
In errors like:
RawVec
being defined asRawVec<T, A: Alloc = Global>
, the error is better written asIn fact, that is already what happens when
foo
is not an ADT, because in that case, the diagnostic handler doesn't try to highlight something, and just uses theDisplay
trait instead of its own logic.e.g.