-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Modify primary span label for E0308 #106399
Conversation
r? @nagisa (rustbot has picked a reviewer for you, use r? to override) |
This comment was marked as outdated.
This comment was marked as outdated.
10e1dc0
to
3ccdaab
Compare
This comment was marked as resolved.
This comment was marked as resolved.
3ccdaab
to
c1caae9
Compare
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 haven't read the code in detail, but the changes to the diagnostics look really nice; I especially appreciate showing the generic parameters to types and removing the struct/enum/reference
prefix at the same time, it makes it feel more clear and less noisy at the same time :)
c1caae9
to
5fad8b5
Compare
This comment was marked as resolved.
This comment was marked as resolved.
5fad8b5
to
dc6cdf0
Compare
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
af1e93b
to
9eecea8
Compare
This comment was marked as resolved.
This comment was marked as resolved.
9eecea8
to
f316d81
Compare
@@ -89,7 +89,7 @@ error[E0308]: mismatched types | |||
LL | impl<T> S1<T, u8> { | |||
| - this type parameter | |||
LL | const C: S1<u8, u8> = Self(0, 1); | |||
| ^^^^^^^^^^ expected `u8`, found type parameter `T` | |||
| ^^^^^^^^^^ expected `S1<u8, u8>`, found `S1<T, u8>` |
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.
Hm, I think this runs a risk of being unreadable when the type has many big generics, or a small mismatching generic in the between multiple large ones (as could be the case with e.g. futures code, as we've have found out many times before.)
I think we should continue using the convention of _
out substs that already match and don't provide much value (at least after some threshold of type complexity.)
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.
The label is using the "long types" machinery which will cap the width to at most 15 chars (or revert to the current behavior if that would cause the label to lose meaning). The "hiding matching generics with _
" logic is not geared towards getting a text output, not can be directly joined with the long types one. I could see if I can make it easy to turn DiagnosticString
into String
, and then try them all in order and use whichever is shorter, but I do feel like the current approach "is enough" before bolting more logic onto a single PR (to make it easier to review each step independently).
@@ -2,7 +2,7 @@ error[E0308]: mismatched types | |||
--> $DIR/issue-24322.rs:8:29 | |||
| | |||
LL | let x: &fn(&B) -> u32 = &B::func; | |||
| -------------- ^^^^^^^^ expected fn pointer, found fn item | |||
| -------------- ^^^^^^^^ expected `&for<'a> fn(&'a B) -> u32`, found `&for<'a> fn(&'a B) -> u32 {B::func}` |
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.
Hm, I think we should somehow try to not include the for<_>
s here, if at all possible. This is not a syntax that is commonly encountered, and it is routinely a source of confusion or questions, so not revealing it unless truly necessary I think is a worthwhile improvement.
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 can do 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.
I went further and also removed the lifetime names in all trimmed paths, which might be contentious. I did it in two different commits so that we can drop the second one if you disagree with it.
@@ -16,7 +16,7 @@ LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok... | |||
LL | | Ok("") | |||
LL | | )))))))))))))))))))))))))))))) | |||
LL | | )))))))))))))))))))))))))))))); | |||
| |__________________________________^ expected struct `Atype`, found enum `Result` | |||
| |__________________________________^ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>` |
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.
Is there a reason we're using ...
instead of _
?
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.
Yeah, the long types machinery is using ...
. When that was merged I had changed it to _
but was asked to get it back to what you see now. I don't have a strong position on the matter.
@@ -4,14 +4,14 @@ error[E0308]: arguments to this function are incorrect | |||
LL | foo(f, w); | |||
| ^^^ | |||
| | |||
note: expected `i32`, found `u32` | |||
note: expected fn pointer, found fn item |
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.
Hm, I think this note isn’t particularly helpful. Even harmful perhaps. “Compatible” fn items can always coerce to fn pointers, but the note may impress upon the reader that this isn’t always the case for some reason. So there is definitely something more the compiler could say. I think the 2nd note is pretty good and could potentially stay as the only note in this error.
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.
Yeah, this is supposed to be "expected fn(i32)
, found fn(u32) {f}
", but I didn't modify the labels for the special cases (like this one) to keep the diff much shorter. I can go all out and apply the changes in more places to fix this one case, but it will dramatically increase the size of the PR.
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 it should be ok to land this here, provided we later also have a structured suggestion for functions. I'm pretty sure this is not the only place where we are already having this unfortunate output and where we should be explicit with a note (which I thought we had) about that behavior.
impl<'tcx> fmt::Display for TypeError<'tcx> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
impl<'tcx> TypeError<'tcx> { | ||
pub fn to_string(self, tcx: TyCtxt<'tcx>) -> String { |
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.
Given that this is always in the error path, allocating a String
is probably fine, though I think it would probably not be too onerous to retain the more optimal fmt
approach by having a structure that combines TyCtxt
with TypeError
, somewhat like this:
impl<'tcx> TypeError<'tcx> {
fn with(self, tcx: TyCtxt<'tcx>) -> TypeErrorWithTyCtxt<'tcx> { todo!() }
}
impl<'tcx> std::fmt::Display for TypeErrorWithTyCtxt<'tcx> { ... }
It would probably be terser, and I think we use this kind of pattern elsewhere in the codebase already, so it isn’t that unconventional.
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.
Maybe turning this to be Cow would be good enough?
2e55fe8
to
6e9f60b
Compare
--> $DIR/two-mismatch-notes.rs:10:9 | ||
| | ||
LL | foo(f, w); | ||
| ^ | ||
= note: expected fn pointer `fn(i32)` | ||
found fn item `fn(u32) {f}` | ||
note: expected `i32`, found `isize` | ||
= note: when the arguments and return types match, functions can be coerced to function pointers |
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.
Added this note to partially address the comment above.
98f610d
to
c36437b
Compare
This comment was marked as resolved.
This comment was marked as resolved.
c36437b
to
5a8f2a3
Compare
☔ The latest upstream changes (presumably #107021) made this pull request unmergeable. Please resolve the merge conflicts. |
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.
r=me. This looks great. I could only muster enough willpower to look through like 50% of the changed stderrs, but I didn’t see any moajor regressions in what I’ve looked at and overall improvement is very welcome and nice!
Sorry for the late review!
The previous output was unintuitive to users.
5a8f2a3
to
449dfc6
Compare
@bors r=nagisa |
☀️ Test successful - checks-actions |
Finished benchmarking commit (f361413): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. |
Looking at the reactions to https://hachyderm.io/@ekuber/109622160673605438, a lot of people seem to have trouble understanding the current output, where the primary span label on type errors talks about the specific types that diverged, but these can be deeply nested type parameters. Because of that we could see "expected i32, found u32" in the label while the note said "expected Vec, found Vec". This understandably confuses people. I believe that once people learn to read these errors it starts to make more sense, but this PR changes the output to be more in line with what people might expect, without sacrificing terseness.
Fix #68220.