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

Modify primary span label for E0308 #106399

Merged
merged 10 commits into from
Jan 31, 2023
Merged

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Jan 3, 2023

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.

@rustbot
Copy link
Collaborator

rustbot commented Jan 3, 2023

r? @nagisa

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 3, 2023
@rust-log-analyzer

This comment was marked as outdated.

@rust-log-analyzer

This comment was marked as resolved.

Copy link
Member

@jyn514 jyn514 left a 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 :)

@rust-log-analyzer

This comment was marked as resolved.

@rustbot
Copy link
Collaborator

rustbot commented Jan 4, 2023

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@estebank estebank force-pushed the type-err-span-label branch 2 times, most recently from af1e93b to 9eecea8 Compare January 4, 2023 05:57
@bors

This comment was marked as resolved.

compiler/rustc_hir_analysis/src/check/check.rs Outdated Show resolved Hide resolved
@@ -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>`
Copy link
Member

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.)

Copy link
Contributor Author

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}`
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can do that.

Copy link
Contributor Author

@estebank estebank Jan 6, 2023

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<..., ...>, ...>`
Copy link
Member

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 _?

Copy link
Contributor Author

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
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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 {
Copy link
Member

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.

Copy link
Contributor Author

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?

compiler/rustc_middle/src/ty/error.rs Outdated Show resolved Hide resolved
@estebank estebank force-pushed the type-err-span-label branch 2 times, most recently from 2e55fe8 to 6e9f60b Compare January 6, 2023 18:41
--> $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
Copy link
Contributor Author

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.

@estebank estebank force-pushed the type-err-span-label branch 2 times, most recently from 98f610d to c36437b Compare January 11, 2023 21:40
@bors

This comment was marked as resolved.

@bors
Copy link
Contributor

bors commented Jan 18, 2023

☔ The latest upstream changes (presumably #107021) made this pull request unmergeable. Please resolve the merge conflicts.

Copy link
Member

@nagisa nagisa left a 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!

@estebank
Copy link
Contributor Author

@bors r=nagisa

@bors
Copy link
Contributor

bors commented Jan 30, 2023

📌 Commit 449dfc6 has been approved by nagisa

It is now in the queue for this repository.

@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 Jan 30, 2023
@bors
Copy link
Contributor

bors commented Jan 31, 2023

⌛ Testing commit 449dfc6 with merge f361413...

@bors
Copy link
Contributor

bors commented Jan 31, 2023

☀️ Test successful - checks-actions
Approved by: nagisa
Pushing f361413 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jan 31, 2023
@bors bors merged commit f361413 into rust-lang:master Jan 31, 2023
@rustbot rustbot added this to the 1.69.0 milestone Jan 31, 2023
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (f361413): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This 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.

mean range count
Regressions ❌
(primary)
2.6% [1.3%, 4.0%] 4
Regressions ❌
(secondary)
2.3% [0.6%, 6.9%] 42
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.6% [1.3%, 4.0%] 4

Cycles

This benchmark run did not return any relevant results for this metric.

@estebank estebank deleted the type-err-span-label branch November 9, 2023 05:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Diagnostics show different expected and found types
7 participants