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

Detect type mismatch due to loop that might never iterate #100094

Merged
merged 1 commit into from
Aug 6, 2022

Conversation

lyming2007
Copy link

@lyming2007 lyming2007 commented Aug 3, 2022

When loop as tail expression causes a miss match type E0308 error, recursively get the return statement and add diagnostic information on it.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 3, 2022
@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @lcnr (or someone else) soon.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 3, 2022
compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
@@ -1552,12 +1576,72 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}

err.emit_unless(unsized_return);
if ret_vec.len() > 0 {
if let Some(expr) = expression {
let mut addtion_err = fcx.tcx.sess.diagnostic().span_note_diag(expr.span, "the function expects a value to always be returned, but loops might run zero times");
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't emit an additional note here -- instead, we should append this to err that is referenced above.

if ret_vec.len() > 0 {
if let Some(expr) = expression {
let mut addtion_err = fcx.tcx.sess.diagnostic().span_note_diag(expr.span, "the function expects a value to always be returned, but loops might run zero times");
for i in 0..ret_vec.len() {
Copy link
Member

@compiler-errors compiler-errors Aug 3, 2022

Choose a reason for hiding this comment

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

This should be limited to something reasonable like 3, and if there are >3, then say something like "... and other returns" or something like that.

Copy link
Author

Choose a reason for hiding this comment

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

what do you mean by this? Sounds like a new issue for me.
Can you give me more details that we should emit?

Copy link
Contributor

@estebank estebank Aug 5, 2022

Choose a reason for hiding this comment

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

He means something like:

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 |
LL |         return i;
   |         -------- if the loop doesn't execute, this value would never get returned
...
LL |         return i;
   |         -------- if the loop doesn't execute, this value would never get returned
...
LL |         return i;
   |         -------- if the loop doesn't execute, this value would never get returned
   = note: if the loop doesn't execute, 5 other values would never get returned

Copy link
Author

Choose a reason for hiding this comment

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

created #100285 and assigned to myself

compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
loop_span,
"this might have zero elements to iterate on".to_string(),
);
addtion_err.help("return a value for the case when the loop has zero elements to iterate on, and consider changing the return type to account for that possibility");
Copy link
Member

Choose a reason for hiding this comment

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

I think the original issue #98982 was asking to make this into a suggestion, i.e. have the compiler suggest wrapping the return values in Some(..) and then returning 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 think we need better machinery for default values (damn! I just realized that we could opportunistically programatically get that from the Default impl of types!), I'm ok with a help for now.

compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
@@ -1481,6 +1481,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {

let mut err;
let mut unsized_return = false;
let mut ret_vec: Vec<hir::HirId> = Vec::new(); // collect return expression, record HirId to save memory
Copy link
Contributor

Choose a reason for hiding this comment

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

It's fine, hir::Expr should be cheap enough for this, and we are already emitting the error, the allocation will have to happen either way, we wouldn't be pessimizing the happy path.

compiler/rustc_typeck/src/check/coercion.rs Outdated Show resolved Hide resolved
loop_span,
"this might have zero elements to iterate on".to_string(),
);
addtion_err.help("return a value for the case when the loop has zero elements to iterate on, and consider changing the return type to account for that possibility");
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need better machinery for default values (damn! I just realized that we could opportunistically programatically get that from the Default impl of types!), I'm ok with a help for now.

@estebank
Copy link
Contributor

estebank commented Aug 3, 2022

r? @estebank

"the function expects a value to always be returned, but loops might run zero times",
);
err.help(
"return a value for the case when the loop has zero elements to iterate on, and \
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"return a value for the case when the loop has zero elements to iterate on, and \
"return a value for the case when the loop has zero elements to iterate on, or \

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 left some minor nitpicks, but after addressing them let me know and I'll approve. r=me.

@estebank estebank changed the title implement #98982 Detect type mismatch due to loop that might never iterate Aug 5, 2022
@lyming2007 lyming2007 force-pushed the issue-98982 branch 2 times, most recently from a4f876d to 6c86640 Compare August 5, 2022 16:58
when loop as tail expression for miss match type E0308 error, recursively get
the return statement and add diagnostic information on it
use rustc_hir::intravisit to collect the return expression
	modified:   compiler/rustc_typeck/src/check/coercion.rs
	new file:   src/test/ui/typeck/issue-98982.rs
	new file:   src/test/ui/typeck/issue-98982.stderr
@estebank
Copy link
Contributor

estebank commented Aug 5, 2022

@bors r+

@bors
Copy link
Contributor

bors commented Aug 5, 2022

📌 Commit 9815667 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 Aug 5, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 6, 2022
…iaskrgr

Rollup of 4 pull requests

Successful merges:

 - rust-lang#100094 (Detect type mismatch due to loop that might never iterate)
 - rust-lang#100132 (Use (actually) dummy place for let-else divergence)
 - rust-lang#100167 (Recover `require`, `include` instead of `use` in item)
 - rust-lang#100193 (Remove more Clean trait implementations)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit b0b798e into rust-lang:master Aug 6, 2022
@rustbot rustbot added this to the 1.65.0 milestone Aug 6, 2022
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 added a commit to rust-lang-ci/rust that referenced this pull request May 5, 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.

7 participants