[rust-dev] Update: break/cont/ret in blocks

Marijn Haverbeke marijnh at gmail.com
Tue Mar 27 11:37:09 PDT 2012


Hi list,

I've pushed a series of patches that implement an alternate `for` loop
syntax -- when the `for` keyword is followed by a block-style call
({||}-block as last argument, outside the parentheses), the block is
treated specially: it must return (), but the function argument that
it is passed to must be a function type that returns bool. The idea is
that this is used to call iterators that stop iterating when their
block returns false. An implicit return value of true will be wired
into the block, and any instances of `cont` will make the block return
true, break will make the block return false. See [1] for some
test/example code.

I've added vec::each, str::each, and list::each functions for use with
this construct. They are expected to be replaced by something more
refined (the iter library, probably) down the line.

When the block in a `for` loop like this contains a `ret` statement
(which are now disallowed in regular blocks), it will cause a return
from the outer function. It does this by closing over its parent's
return pointer and a flag that it sets when returning, which the outer
function checks when the call returns. All this only happens when an
actual return is present, so you don't pay for it when you don't use
it.

I've replaced a big chunk of the for loops in the codebase with `for
vec::each(v) {|elt| ... }` constructs. This produced a small slowdown
in our cycle times (a little over 1%), which is expected, since more
inlining and optimization will be needed on the side of LLVM to pummel
these into tight loops. Small benchmarks show that the performance of
these new-style for loops in the same ballpark, but not the same as,
the performance of the primitive for construct (~30% slower for tight,
long loops). I expect we'll be able to squeeze out a bit more by
making vec::each more optimizable.

This was all more or less foreshadowed in the discussion of bug #1619
[2], but (as usual) I took some liberty in the implementation. Comment
here if you feel something should be done differently. If there are no
serious objections, I'd like to remove support for the old for syntax
soon.

[1]: https://github.com/mozilla/rust/blob/master/src/test/run-pass/ret-break-cont-in-block.rs
[2]: https://github.com/mozilla/rust/issues/1619

Best,
Marijn


More information about the Rust-dev mailing list