Skip to content

Commit dee9d7f

Browse files
committed
auto merge of #8945 : alexcrichton/rust/ifmt-dont-move, r=thestinger
2 parents c14daba + 7e70247 commit dee9d7f

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

src/libsyntax/ext/ifmt.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,18 +588,22 @@ impl Context {
588588
// foo(bar(&1))
589589
// the lifetime of `1` doesn't outlast the call to `bar`, so it's not
590590
// vald for the call to `foo`. To work around this all arguments to the
591-
// fmt! string are shoved into locals.
591+
// fmt! string are shoved into locals. Furthermore, we shove the address
592+
// of each variable because we don't want to move out of the arguments
593+
// passed to this function.
592594
for (i, &e) in self.args.iter().enumerate() {
593595
if self.arg_types[i].is_none() { loop } // error already generated
594596

595597
let name = self.ecx.ident_of(fmt!("__arg%u", i));
598+
let e = self.ecx.expr_addr_of(e.span, e);
596599
lets.push(self.ecx.stmt_let(e.span, false, name, e));
597600
locals.push(self.format_arg(e.span, Left(i), name));
598601
}
599602
for (&name, &e) in self.names.iter() {
600603
if !self.name_types.contains_key(&name) { loop }
601604

602605
let lname = self.ecx.ident_of(fmt!("__arg%s", name));
606+
let e = self.ecx.expr_addr_of(e.span, e);
603607
lets.push(self.ecx.stmt_let(e.span, false, lname, e));
604608
names[*self.name_positions.get(&name)] =
605609
Some(self.format_arg(e.span, Right(name), lname));
@@ -643,7 +647,7 @@ impl Context {
643647
Right(s) => *self.name_types.get(&s)
644648
};
645649

646-
let argptr = self.ecx.expr_addr_of(sp, self.ecx.expr_ident(sp, ident));
650+
let argptr = self.ecx.expr_ident(sp, ident);
647651
let fmt_trait = match ty {
648652
Unknown => "Default",
649653
Known(tyname) => {

src/test/run-pass/ifmt.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ pub fn main() {
215215

216216
test_write();
217217
test_print();
218+
219+
// make sure that format! doesn't move out of local variables
220+
let a = ~3;
221+
format!("{:?}", a);
222+
format!("{:?}", a);
218223
}
219224

220225
// Basic test to make sure that we can invoke the `write!` macro with an

0 commit comments

Comments
 (0)