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

Remove suggestion about iteration count in coerce #123125

Merged
merged 1 commit into from
May 5, 2024

Conversation

gurry
Copy link
Contributor

@gurry gurry commented Mar 27, 2024

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.

@rustbot
Copy link
Collaborator

rustbot commented Mar 27, 2024

r? @estebank

rustbot has assigned @estebank.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@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 Mar 27, 2024
@bors
Copy link
Contributor

bors commented Mar 27, 2024

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

@gurry gurry force-pushed the 122561-bad-note-non-zero-loop-iters-2 branch from bb6bd83 to 3ca3dca Compare March 29, 2024 05:15
@rustbot
Copy link
Collaborator

rustbot commented Mar 29, 2024

Some changes occurred in src/tools/cargo

cc @ehuss

@gurry gurry force-pushed the 122561-bad-note-non-zero-loop-iters-2 branch from 3ca3dca to 9c5c276 Compare March 29, 2024 05:21
@gurry
Copy link
Contributor Author

gurry commented Mar 29, 2024

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

Rebased

@gurry
Copy link
Contributor Author

gurry commented Mar 29, 2024

Some changes occurred in src/tools/cargo

cc @ehuss

This was due to a bad commit, which I've fixed now.

Copy link
Contributor

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

  1. when the range is known to never run, mention that and modify the other messages to account for it so they make sense
  2. when there's loop { return val; } with no conditions, to explain that "rustc is not smart enough to understand that val 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)
  3. 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)

Comment on lines 11 to 30
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
|
Copy link
Contributor

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?

Copy link
Contributor Author

@gurry gurry Mar 30, 2024

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.

Comment on lines -15 to -19
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
Copy link
Contributor

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.

Copy link
Contributor Author

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.

compiler/rustc_hir_typeck/src/coercion.rs Outdated Show resolved Hide resolved
@estebank estebank added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Mar 29, 2024
@gurry
Copy link
Contributor Author

gurry commented Mar 30, 2024

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:

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 for loop desugaring not the whether the loop iterates or not (see this comment for details: #122679 (comment))

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.

  1. when the range is known to never run, mention that and modify the other messages to account for it so they make sense

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.

  1. when there's loop { return val; } with no conditions, to explain that "rustc is not smart enough to understand that val 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)
  2. 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)

Oddly enough, the plain vanilla loop actually doesn't trigger the type mismatch error. Both cases 2. and 3. you mentioned compile without any error as you can see in this Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c2bc903c88d86cd88cb23e9b88f99d88). So the question of adding any explanation for them does not arise.

@estebank
Copy link
Contributor

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 (), sorry".

@gurry
Copy link
Contributor Author

gurry commented Mar 30, 2024

It honestly might be reasonable to explain "yes, this desugars to something else that evaluates to (), sorry".

"Desugar" may not be a term well understood outside of compiler engineering. Maybe something along the lines of, "for loops always evaluate to type ()".

@gurry gurry force-pushed the 122561-bad-note-non-zero-loop-iters-2 branch from 9c5c276 to a2c152c Compare April 1, 2024 05:29
@gurry
Copy link
Contributor Author

gurry commented Apr 1, 2024

It honestly might be reasonable to explain "yes, this desugars to something else that evaluates to (), sorry".

"Desugar" may not be a term well understood outside of compiler engineering. Maybe something along the lines of, "for loops always evaluate to type ()".

I have now added the note "(for|while) loops evaluate to unit type ()".

@rustbot label -S-waiting-on-author

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 1, 2024
|
LL ~ }
LL + /* `Option<()>` value */
|
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@estebank please review

@gurry gurry force-pushed the 122561-bad-note-non-zero-loop-iters-2 branch from a2c152c to 2b211b1 Compare April 9, 2024 12:22
@rust-log-analyzer

This comment has been minimized.

@gurry gurry force-pushed the 122561-bad-note-non-zero-loop-iters-2 branch from 2b211b1 to fa73e37 Compare April 9, 2024 13:17
@estebank
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Apr 19, 2024

📌 Commit fa73e37 has been approved by estebank

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 Apr 19, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 19, 2024
…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.
@bors
Copy link
Contributor

bors commented Apr 19, 2024

⌛ Testing commit fa73e37 with merge b16d83c...

@bors
Copy link
Contributor

bors commented Apr 19, 2024

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 19, 2024
@rust-log-analyzer

This comment has been minimized.

@gurry gurry force-pushed the 122561-bad-note-non-zero-loop-iters-2 branch from fa73e37 to 2b71944 Compare April 19, 2024 13:01
@gurry
Copy link
Contributor Author

gurry commented Apr 20, 2024

Build had failed due to a merge conflict. Rebased now. Please re-approve @estebank

@bors
Copy link
Contributor

bors commented Apr 30, 2024

☔ 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
@gurry gurry force-pushed the 122561-bad-note-non-zero-loop-iters-2 branch from 2b71944 to 6289ed8 Compare April 30, 2024 09:27
@gurry
Copy link
Contributor Author

gurry commented Apr 30, 2024

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

Rebased

@gurry
Copy link
Contributor Author

gurry commented May 4, 2024

@estebank Failing build fixed. Please review again

@Dylan-DPC
Copy link
Member

@bors r=estebank

@bors
Copy link
Contributor

bors commented May 5, 2024

📌 Commit 6289ed8 has been approved by estebank

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented May 5, 2024

🌲 The tree is currently closed for pull requests below priority 9999. This pull request will be tested once the tree is reopened.

@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 May 5, 2024
@bors
Copy link
Contributor

bors commented May 5, 2024

⌛ Testing commit 6289ed8 with merge 06e88c3...

@bors
Copy link
Contributor

bors commented May 5, 2024

☀️ Test successful - checks-actions
Approved by: estebank
Pushing 06e88c3 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label May 5, 2024
@bors bors merged commit 06e88c3 into rust-lang:master May 5, 2024
7 checks passed
@rustbot rustbot added this to the 1.80.0 milestone May 5, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (06e88c3): 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)
3.8% [3.8%, 3.8%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.7% [-0.7%, -0.7%] 1
Improvements ✅
(secondary)
-5.2% [-5.2%, -5.2%] 1
All ❌✅ (primary) 1.5% [-0.7%, 3.8%] 2

Cycles

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

Binary size

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

Bootstrap: 676.151s -> 673.364s (-0.41%)
Artifact size: 315.84 MiB -> 315.81 MiB (-0.01%)

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
7 participants