-
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
Remove suggestion about iteration count in coerce #123125
Remove suggestion about iteration count in coerce #123125
Conversation
☔ The latest upstream changes (presumably #123006) made this pull request unmergeable. Please resolve the merge conflicts. |
bb6bd83
to
3ca3dca
Compare
Some changes occurred in src/tools/cargo cc @ehuss |
3ca3dca
to
9c5c276
Compare
Rebased |
This was due to a bad commit, which I've fixed now. |
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'm not entirely on board with completely removing the previous message, because I feel that we'd be giving an obscure message still. Instead I would add logic to it in order to detect a few cases:
- when the range is known to never run, mention that and modify the other messages to account for it so they make sense
- when there's
loop { return val; }
with no conditions, to explain that "rustc is not smart enough to understand thatval
will always be returned" (although ideally we'd have a lang semantic change to account for that so that we don't error at all in that case) - when there's a
loop { if condition { return val; } }
with the current explanation (tweaked to make it clearer that it's not just the loop might not run even once, but also that it might run multiple times but never reach the return before the loop breaks)
tests/ui/typeck/issue-98982.stderr
Outdated
note: the function expects a value to always be returned, but loops might run zero times | ||
--> $DIR/issue-98982.rs:2:5 | ||
| | ||
LL | for i in 0..0 { | ||
| ^^^^^^^^^^^^^ this might have zero elements to iterate on | ||
LL | return i; | ||
| -------- if the loop doesn't execute, this value would never get returned | ||
help: return a value for the case when the loop has zero elements to iterate on | ||
help: consider returning a value here | ||
| | ||
LL ~ } | ||
LL ~ /* `i32` value */ | ||
| | ||
help: otherwise consider changing the return type to account for that possibility | ||
| | ||
LL ~ fn foo() -> Option<i32> { | ||
LL | for i in 0..0 { | ||
LL ~ return Some(i); | ||
LL ~ } | ||
LL ~ None | ||
| |
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 think that this reversal is reasonable, because the explanation for this case is exactly right: for i in 0..0
will never iterate, right?
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, for i in 0..0
will never iterate, but that is not what is causing the error since for i in 0..100
which definitely iterates still results in the same error (see #123125 (comment)).
Since the error is not due to iteration count, the reversal is reasonable IMHO.
note: the function expects a value to always be returned, but loops might run zero times | ||
--> $DIR/issue-100285.rs:2:5 | ||
| | ||
LL | for i in 0..0 { | ||
| ^^^^^^^^^^^^^ this might have zero elements to iterate on |
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.
Same here. We should even be detecting explicitly known to never iterate ranges, where the start and the end of a ..
range are the same, because the entire thing is for sure dead code.
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, it would be a good idea to warn the user that for i in 0..0 { ... }
is dead code. Maybe I can do that in a different PR.
I agree that we should provide more context. However, any notes and explanations that talk about the loop iteration count are flawed IMHO because the error has nothing to do with loop iteration count. For example, below snippet in which the loop runs zero times triggers the type mismatch error: fn test() -> bool {
for i in 0..0 {
return true;
}
} but so does this one in which the loop runs 5 times: fn test() -> bool {
for i in 0..5 {
return true;
}
} (Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ff4e48a30ffbc4f0f344bd6ccae27d5f) The reality is that the error actually stems from the peculiar structure of the In light of this underlying reality, the current set of notes (like "the function expects a value to always be returned, but loops might run zero times") are incorrect and somewhat misleading because they seem to attribute the error to the loop iteration count. If we must add any explanation, it should be about the for loop desugaring which is the actual cause. However, I couldn't find any good way to word it which would not get into the compiler internals. If you can suggest a user friendly text I'd love to add that.
I actually had done just that in my now abandoned PR #122679, wherein I computed the actual iteration count for the loop and showed different notes depending on that, but then I realised no amount sophistication in suggestions centered on loop iteration count actually help here because the cause of the error is entirely something else.
Oddly enough, the plain vanilla |
Thanks! The comment on the other PR gives appropriate context. Now I'm trying to think what the appropriate explanation of the situation might be. It honestly might be reasonable to explain "yes, this desugars to something else that evaluates to |
"Desugar" may not be a term well understood outside of compiler engineering. Maybe something along the lines of, "for loops always evaluate to type |
9c5c276
to
a2c152c
Compare
I have now added the note "(for|while) loops evaluate to unit type @rustbot label -S-waiting-on-author |
| | ||
LL ~ } | ||
LL + /* `Option<()>` value */ | ||
| |
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.
Here we are providing effectively the same suggestion twice. We need to find a way to avoid one or the other (or ideally, unify the logic to a single place, particularly because the pre-existing suggestion gives you the actual value to use in this case).
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.
Done.
The suggestion is now invoked from emit_type_mismatch_suggestions()
in demand.rs
which ensures it will not be called if the other suggestion has already been emitted.
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.
@estebank please review
a2c152c
to
2b211b1
Compare
This comment has been minimized.
This comment has been minimized.
2b211b1
to
fa73e37
Compare
@bors r+ |
…iters-2, r=estebank Remove suggestion about iteration count in coerce Fixes rust-lang#122561 The iteration count-centric suggestion was implemented in PR rust-lang#100094, but it was based on the wrong assumption that the type mismatch error depends on the number of times the loop iterates. As it turns out, that is not true (see this comment for details: rust-lang#122679 (comment)) This PR attempts to remedy the situation by changing the suggestion from the one centered on iteration count to a simple suggestion to add a return value. It should also fix rust-lang#100285 by simply making it redundant.
💔 Test failed - checks-actions |
This comment has been minimized.
This comment has been minimized.
fa73e37
to
2b71944
Compare
Build had failed due to a merge conflict. Rebased now. Please re-approve @estebank |
☔ The latest upstream changes (presumably #124398) made this pull request unmergeable. Please resolve the merge conflicts. |
and replace it with a simple note suggesting returning a value. The type mismatch error was never due to how many times the loop iterates. It is more because of the peculiar structure of what the for loop desugars to. So the note talking about iteration count didn't make sense
2b71944
to
6289ed8
Compare
Rebased |
@estebank Failing build fixed. Please review again |
@bors r=estebank |
🌲 The tree is currently closed for pull requests below priority 9999. This pull request will be tested once the tree is reopened. |
☀️ Test successful - checks-actions |
Finished benchmarking commit (06e88c3): 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. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 676.151s -> 673.364s (-0.41%) |
Fixes #122561
The iteration count-centric suggestion was implemented in PR #100094, but it was based on the wrong assumption that the type mismatch error depends on the number of times the loop iterates. As it turns out, that is not true (see this comment for details: #122679 (comment))
This PR attempts to remedy the situation by changing the suggestion from the one centered on iteration count to a simple suggestion to add a return value.
It should also fix #100285 by simply making it redundant.