-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Fix behaviour of divergence in while loop conditions #51049
Conversation
}; | ||
|
||
self.with_breakable_ctxt(expr.id, ctxt, || { | ||
let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || { | ||
self.check_expr_has_type_or_error(&cond, tcx.types.bool); | ||
let cond_diverging = self.diverges.get(); |
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.
So what's confusing me here: there is somehow an implicit break
should the condition be false (this is why may_break
used to be considered true
), and I can't see where that is accounted for.
For example, does this code accept:
let x: ! = {
while false { return; };
};
( Do we have a test for this? It annoys me that this question is so hard to answer =) )
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.
Traditionally we have considered while
loops as always potentially breaking — but it seems like your change could allow us to handle cases like this one (for example)
'a: loop {
let x: ! = {
while (continue 'a) { };
};
}
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.
For example, does this code accept:
No, this code fails to type-check both in the current version and after this PR. I'll add a test for it, though. The divergence of the body of the loop is completely ignored at the moment — it's just the condition that is taken into account. This PR ignores divergence in the condition too if break
was involved.
Actually, even a case like:
let _: ! = 'a: while continue 'a {};
doesn't type-check at the moment, though intuitively it could do. (This isn't affected by this PR.) I think such a change would be more in scope for #51053, though. It's not breaking anything at the moment (as it's conservative).
@@ -3867,6 +3867,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { | |||
self.diverges.set(cond_diverging); | |||
}); | |||
|
|||
if ctxt.may_break { |
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.
It seems like not having this before was the obvious bug...
I've added a couple more tests. The actual error messages look a little weird due to #50085, but that's an unrelated problem. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
This fixes `'a: while break 'a {};` being treated as diverging, by tracking break expressions in the same way as in `loop` expressions.
6003dd2
to
d5bf4de
Compare
@@ -3853,6 +3853,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { | |||
self.diverges.set(cond_diverging); |
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.
Ah, this is the bit I was missing before (which ignores the divergence of the body). Very good.
@bors r+ |
📌 Commit d5bf4de has been approved by |
…omatsakis Fix behaviour of divergence in while loop conditions This fixes `'a: while break 'a {};` being treated as diverging, by tracking break expressions in the same way as in `loop` expressions. Fixes rust-lang#50856. r? @nikomatsakis
💥 Test timed out |
This fixes
'a: while break 'a {};
being treated as diverging, by tracking break expressions in the same way as inloop
expressions.Fixes #50856.
r? @nikomatsakis