diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2014-12-20 21:57:47 +0200 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2014-12-27 23:55:14 +0200 |
| commit | 68a7f1b5e37f3b8a83def4e9cb4d02aef33b8dbf (patch) | |
| tree | 2ea6fd7fd818b35e983b4a74807eed631b9853cf /src/libsyntax | |
| parent | 17b3c1107a42048209a345924bf6045861c3c498 (diff) | |
| download | rust-68a7f1b5e37f3b8a83def4e9cb4d02aef33b8dbf.tar.gz rust-68a7f1b5e37f3b8a83def4e9cb4d02aef33b8dbf.zip | |
syntax: turn the match-call generated by format_args inside-out.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/format.rs | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 781e6d05803..dc5a899aa6b 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -559,9 +559,43 @@ impl<'a, 'b> Context<'a, 'b> { // Now create a vector containing all the arguments let args = locals.into_iter().chain(names.into_iter().map(|a| a.unwrap())); - // Now create the fmt::Arguments struct with all our locals we created. - let args_slice = self.ecx.expr_vec_slice(self.fmtsp, args.collect()); + let args_array = self.ecx.expr_vec(self.fmtsp, args.collect()); + + // Constructs an AST equivalent to: + // + // match (&arg0, &arg1) { + // (tmp0, tmp1) => args_array + // } + // + // It was: + // + // let tmp0 = &arg0; + // let tmp1 = &arg1; + // args_array + // + // Because of #11585 the new temporary lifetime rule, the enclosing + // statements for these temporaries become the let's themselves. + // If one or more of them are RefCell's, RefCell borrow() will also + // end there; they don't last long enough for args_array to use them. + // The match expression solves the scope problem. + // + // Note, it may also very well be transformed to: + // + // match arg0 { + // ref tmp0 => { + // match arg1 => { + // ref tmp1 => args_array } } } + // + // But the nested match expression is proved to perform not as well + // as series of let's; the first approach does. + let pat = self.ecx.pat_tuple(self.fmtsp, pats); + let arm = self.ecx.arm(self.fmtsp, vec!(pat), args_array); + let head = self.ecx.expr(self.fmtsp, ast::ExprTup(heads)); + let result = self.ecx.expr_match(self.fmtsp, head, vec!(arm)); + + let args_slice = self.ecx.expr_addr_of(self.fmtsp, result); + // Now create the fmt::Arguments struct with all our locals we created. let (fn_name, fn_args) = if self.all_pieces_simple { ("new", vec![pieces, args_slice]) } else { @@ -582,58 +616,26 @@ impl<'a, 'b> Context<'a, 'b> { ("with_placeholders", vec![pieces, fmt, args_slice]) }; - let result = self.ecx.expr_call_global(self.fmtsp, vec!( + let body = self.ecx.expr_call_global(self.fmtsp, vec!( self.ecx.ident_of("std"), self.ecx.ident_of("fmt"), self.ecx.ident_of("Arguments"), self.ecx.ident_of(fn_name)), fn_args); - let body = match invocation { + match invocation { Call(e) => { let span = e.span; self.ecx.expr_call(span, e, vec![ - self.ecx.expr_addr_of(span, result) + self.ecx.expr_addr_of(span, body) ]) } MethodCall(e, m) => { let span = e.span; self.ecx.expr_method_call(span, e, m, vec![ - self.ecx.expr_addr_of(span, result) + self.ecx.expr_addr_of(span, body) ]) } - }; - - // Constructs an AST equivalent to: - // - // match (&arg0, &arg1) { - // (tmp0, tmp1) => body - // } - // - // It was: - // - // let tmp0 = &arg0; - // let tmp1 = &arg1; - // body - // - // Because of #11585 the new temporary lifetime rule, the enclosing - // statements for these temporaries become the let's themselves. - // If one or more of them are RefCell's, RefCell borrow() will also - // end there; they don't last long enough for body to use them. The - // match expression solves the scope problem. - // - // Note, it may also very well be transformed to: - // - // match arg0 { - // ref tmp0 => { - // match arg1 => { - // ref tmp1 => body } } } - // - // But the nested match expression is proved to perform not as well - // as series of let's; the first approach does. - let pat = self.ecx.pat_tuple(self.fmtsp, pats); - let arm = self.ecx.arm(self.fmtsp, vec!(pat), body); - let head = self.ecx.expr(self.fmtsp, ast::ExprTup(heads)); - self.ecx.expr_match(self.fmtsp, head, vec!(arm)) + } } fn format_arg(ecx: &ExtCtxt, sp: Span, |
