It seems that loop { }
disables drop checking of code that follows it inside a block.
I saw this pattern used here, and it turns out to be quite useful.
Is this by design and supported by the language (i.e. can I assume it will always work in future versions of Rust)?
It's a syntactic version of if false {...}
. Those checkers doesn't utilize actual value of the condition even if it's hardcoded constant so they still check code inside if false{...}
. But they still perform flow analysis and code after loop {}
is obviously unreachable even without evaluating constants.
Interesting to know that the ck
s are smart enough to see that code after loop { }
will never execute. Does this work the same for any -> !
(eg. panic!() or unreachable!())? Is it safe to assume that code that makes use of this trick will not break in the future?
That's not particularly smart. loop
is by definition an infinite loop, so if there are no break
s or return
s inside it, nothing after it can be reached. This is an easier analysis than, for example, fully const-evaluating the condition of an if
, because the loop
construct is designed to be an endless loop.
Well, loop { }
is non terminating but loop
isn't necessarily endless. It has no formal terminating condition but its body can have arbitrary conditions that will make the loop stop so while loop { }
is trivial to analyse, the general case is probably not. I had used loop
in conjunction with while
to emulate the classical for (init-statement condition ; iteration-expression)
where it is more convenient than just a while
(i.e. when a iteration-expression
must execute when continue
is hit). I guess that borrowck
/dropck
would not be able to correctly deduce that such loop
is endless or not.
That would have a break
or return
, no? The compiler can see that, and even if false { break }
will stop being considered infinite. Similarly, while true {}
is not considered infinite at this level.
I was thinking about a possible panic!()
(that could be caught) inside the loop
, but I'm not knowledgeable about flow analysis so it may be nonsense. The crux of my question is whether the exploitation of loop { }
used in the code is supported by the language and is not subject to breaking
If a panic is caught elsewhere, that doesn't affect the local control flow, deciding whether code after the loop
is reachable. And catch_unwind
always introduces a function boundary too.
The important point is that only with a break
will the code immediately after the loop ever be reachable. With return
or panic!()
control flow will exit straight out of the whole function instead. By the way, using panic!()
or return
should have a similar effect w.r.t. how the borrow checker treats the subsequent code. (I don’t know off the top of my head, how it is with regards to “dropck” as indicated in the code you linked to. One difference between loop {}
and panic
/return
is that the latter two do drop local variables, whereas loop {}
just stays in that loop.)
That is literally what I was saying:
I'm not sure what in this needs correcting.
A panic also diverges, just like an infinite loop. If the code panics, then you can not reach the subsequent instructions, either.
I was not correcting what you said and in fact agreed that loop
is, by definition, non terminating as you noted in you comment.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.