Skip to content

Commit 162be0a

Browse files
committed
---
yaml --- r: 103415 b: refs/heads/auto c: 017c504 h: refs/heads/master i: 103413: 18639f8 103411: 54a2f91 103407: 56796f7 v: v3
1 parent 9312bc8 commit 162be0a

File tree

4 files changed

+43
-14
lines changed

4 files changed

+43
-14
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1313
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1414
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1515
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
16-
refs/heads/auto: ec57db083ff10fc4da0a2f25df5acf1d4398e560
16+
refs/heads/auto: 017c5044895a3f708dee46d64dd3d67dac61145e
1717
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1818
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1919
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336

branches/auto/src/libsyntax/ext/deriving/show.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,6 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
135135
// phew, not our responsibility any more!
136136
format::expand_preparsed_format_args(cx, span,
137137
format_closure,
138-
format_string, exprs, HashMap::new())
138+
format_string, exprs, ~[],
139+
HashMap::new())
139140
}

branches/auto/src/libsyntax/ext/format.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@ struct Context<'a> {
4343
// them.
4444
args: ~[@ast::Expr],
4545
arg_types: ~[Option<ArgumentType>],
46-
// Parsed named expressions and the types that we've found for them so far
46+
// Parsed named expressions and the types that we've found for them so far.
47+
// Note that we keep a side-array of the ordering of the named arguments
48+
// found to be sure that we can translate them in the same order that they
49+
// were declared in.
4750
names: HashMap<~str, @ast::Expr>,
4851
name_types: HashMap<~str, ArgumentType>,
52+
name_ordering: ~[~str],
4953

5054
// Collection of the compiled `rt::Piece` structures
5155
pieces: ~[@ast::Expr],
@@ -63,12 +67,15 @@ struct Context<'a> {
6367
///
6468
/// If parsing succeeds, the second return value is:
6569
///
66-
/// Some((fmtstr, unnamed arguments, named arguments))
67-
fn parse_args(ecx: &mut ExtCtxt, sp: Span,
68-
tts: &[ast::TokenTree]) -> (@ast::Expr, Option<(@ast::Expr, ~[@ast::Expr],
69-
HashMap<~str, @ast::Expr>)>) {
70+
/// Some((fmtstr, unnamed arguments, ordering of named arguments,
71+
/// named arguments))
72+
fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
73+
-> (@ast::Expr, Option<(@ast::Expr, ~[@ast::Expr], ~[~str],
74+
HashMap<~str, @ast::Expr>)>)
75+
{
7076
let mut args = ~[];
7177
let mut names = HashMap::<~str, @ast::Expr>::new();
78+
let mut order = ~[];
7279

7380
let mut p = rsparse::new_parser_from_tts(ecx.parse_sess(),
7481
ecx.cfg(),
@@ -125,12 +132,13 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span,
125132
continue
126133
}
127134
}
135+
order.push(name.to_str());
128136
names.insert(name.to_str(), e);
129137
} else {
130138
args.push(p.parse_expr());
131139
}
132140
}
133-
return (extra, Some((fmtstr, args, names)));
141+
return (extra, Some((fmtstr, args, order, names)));
134142
}
135143

136144
impl<'a> Context<'a> {
@@ -661,10 +669,11 @@ impl<'a> Context<'a> {
661669
locals.push(self.format_arg(e.span, Exact(i),
662670
self.ecx.expr_ident(e.span, name)));
663671
}
664-
for (name, &e) in self.names.iter() {
665-
if !self.name_types.contains_key(name) {
666-
continue
667-
}
672+
for name in self.name_ordering.iter() {
673+
let e = match self.names.find(name) {
674+
Some(&e) if self.name_types.contains_key(name) => e,
675+
Some(..) | None => continue
676+
};
668677

669678
let lname = self.ecx.ident_of(format!("__arg{}", *name));
670679
pats.push(self.ecx.pat_ident(e.span, lname));
@@ -810,8 +819,9 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
810819
tts: &[ast::TokenTree]) -> base::MacResult {
811820

812821
match parse_args(ecx, sp, tts) {
813-
(extra, Some((efmt, args, names))) => {
814-
MRExpr(expand_preparsed_format_args(ecx, sp, extra, efmt, args, names))
822+
(extra, Some((efmt, args, order, names))) => {
823+
MRExpr(expand_preparsed_format_args(ecx, sp, extra, efmt, args,
824+
order, names))
815825
}
816826
(_, None) => MRExpr(ecx.expr_uint(sp, 2))
817827
}
@@ -823,6 +833,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
823833
pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
824834
extra: @ast::Expr,
825835
efmt: @ast::Expr, args: ~[@ast::Expr],
836+
name_ordering: ~[~str],
826837
names: HashMap<~str, @ast::Expr>) -> @ast::Expr {
827838
let arg_types = vec::from_fn(args.len(), |_| None);
828839
let mut cx = Context {
@@ -832,6 +843,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
832843
names: names,
833844
name_positions: HashMap::new(),
834845
name_types: HashMap::new(),
846+
name_ordering: name_ordering,
835847
nest_level: 0,
836848
next_arg: 0,
837849
pieces: ~[],

branches/auto/src/test/run-pass/ifmt.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ pub fn main() {
139139

140140
test_write();
141141
test_print();
142+
test_order();
142143

143144
// make sure that format! doesn't move out of local variables
144145
let a = ~3;
@@ -202,3 +203,18 @@ fn test_format_args() {
202203
let s = format_args!(fmt::format, "hello {}", "world");
203204
t!(s, "hello world");
204205
}
206+
207+
fn test_order() {
208+
// Make sure format!() arguments are always evaluated in a left-to-right
209+
// ordering
210+
fn foo() -> int {
211+
static mut FOO: int = 0;
212+
unsafe {
213+
FOO += 1;
214+
FOO
215+
}
216+
}
217+
assert_eq!(format!("{} {} {a} {b} {} {c}",
218+
foo(), foo(), foo(), a=foo(), b=foo(), c=foo()),
219+
~"1 2 4 5 3 6");
220+
}

0 commit comments

Comments
 (0)