syntax: Expand format!() deterministically

Previously, format!("{a}{b}", a=foo(), b=bar()) has foo() and bar() run in a
nondeterminisc order. This is clearly a non-desirable property, so this commit
uses iteration over a list instead of iteration over a hash map to provide
deterministic code generation of these format arguments.
This commit is contained in:
Alex Crichton 2014-02-27 17:07:27 -08:00
parent ec57db083f
commit 017c504489
3 changed files with 42 additions and 13 deletions

View file

@ -139,6 +139,7 @@ pub fn main() {
test_write();
test_print();
test_order();
// make sure that format! doesn't move out of local variables
let a = ~3;
@ -202,3 +203,18 @@ fn test_format_args() {
let s = format_args!(fmt::format, "hello {}", "world");
t!(s, "hello world");
}
fn test_order() {
// Make sure format!() arguments are always evaluated in a left-to-right
// ordering
fn foo() -> int {
static mut FOO: int = 0;
unsafe {
FOO += 1;
FOO
}
}
assert_eq!(format!("{} {} {a} {b} {} {c}",
foo(), foo(), foo(), a=foo(), b=foo(), c=foo()),
~"1 2 4 5 3 6");
}