Skip to content

Commit fc3f22b

Browse files
committed
syntax: change format_args! to produce fmt::Arguments instead of calling a function with them.
1 parent 3961adc commit fc3f22b

File tree

2 files changed

+29
-66
lines changed

2 files changed

+29
-66
lines changed

src/libsyntax/ext/deriving/show.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,10 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
131131
let format_string = cx.expr_str(span, s);
132132

133133
// phew, not our responsibility any more!
134-
format::expand_preparsed_format_args(cx, span,
135-
format::MethodCall(formatter, meth),
136-
format_string, exprs, Vec::new(),
137-
HashMap::new())
134+
135+
let args = vec![
136+
format::expand_preparsed_format_args(cx, span, format_string,
137+
exprs, vec![], HashMap::new())
138+
];
139+
cx.expr_method_call(span, formatter, meth, args)
138140
}

src/libsyntax/ext/format.rs

Lines changed: 23 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
pub use self::Invocation::*;
1211
use self::ArgumentType::*;
1312
use self::Position::*;
1413

@@ -68,54 +67,33 @@ struct Context<'a, 'b:'a> {
6867
next_arg: uint,
6968
}
7069

71-
pub enum Invocation {
72-
Call(P<ast::Expr>),
73-
MethodCall(P<ast::Expr>, ast::Ident),
74-
}
75-
7670
/// Parses the arguments from the given list of tokens, returning None
7771
/// if there's a parse error so we can continue parsing other format!
7872
/// expressions.
7973
///
80-
/// If parsing succeeds, the second return value is:
74+
/// If parsing succeeds, the return value is:
8175
///
8276
/// Some((fmtstr, unnamed arguments, ordering of named arguments,
8377
/// named arguments))
84-
fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
85-
tts: &[ast::TokenTree])
86-
-> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>,
87-
HashMap<String, P<ast::Expr>>)>) {
78+
fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
79+
-> Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>,
80+
HashMap<String, P<ast::Expr>>)> {
8881
let mut args = Vec::new();
8982
let mut names = HashMap::<String, P<ast::Expr>>::new();
9083
let mut order = Vec::new();
9184

9285
let mut p = ecx.new_parser_from_tts(tts);
93-
// Parse the leading function expression (maybe a block, maybe a path)
94-
let invocation = if allow_method {
95-
let e = p.parse_expr();
96-
if !p.eat(&token::Comma) {
97-
ecx.span_err(sp, "expected token: `,`");
98-
return (Call(e), None);
99-
}
100-
MethodCall(e, p.parse_ident())
101-
} else {
102-
Call(p.parse_expr())
103-
};
104-
if !p.eat(&token::Comma) {
105-
ecx.span_err(sp, "expected token: `,`");
106-
return (invocation, None);
107-
}
10886

10987
if p.token == token::Eof {
11088
ecx.span_err(sp, "requires at least a format string argument");
111-
return (invocation, None);
89+
return None;
11290
}
11391
let fmtstr = p.parse_expr();
11492
let mut named = false;
11593
while p.token != token::Eof {
11694
if !p.eat(&token::Comma) {
11795
ecx.span_err(sp, "expected token: `,`");
118-
return (invocation, None);
96+
return None;
11997
}
12098
if p.token == token::Eof { break } // accept trailing commas
12199
if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) {
@@ -129,13 +107,13 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
129107
ecx.span_err(p.span,
130108
"expected ident, positional arguments \
131109
cannot follow named arguments");
132-
return (invocation, None);
110+
return None;
133111
}
134112
_ => {
135113
ecx.span_err(p.span,
136114
format!("expected ident for named argument, found `{}`",
137115
p.this_token_to_string())[]);
138-
return (invocation, None);
116+
return None;
139117
}
140118
};
141119
let interned_name = token::get_ident(ident);
@@ -158,7 +136,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
158136
args.push(p.parse_expr());
159137
}
160138
}
161-
return (invocation, Some((fmtstr, args, order, names)));
139+
Some((fmtstr, args, order, names))
162140
}
163141

164142
impl<'a, 'b> Context<'a, 'b> {
@@ -497,7 +475,7 @@ impl<'a, 'b> Context<'a, 'b> {
497475

498476
/// Actually builds the expression which the iformat! block will be expanded
499477
/// to
500-
fn to_expr(mut self, invocation: Invocation) -> P<ast::Expr> {
478+
fn into_expr(mut self) -> P<ast::Expr> {
501479
let mut locals = Vec::new();
502480
let mut names = Vec::from_fn(self.name_positions.len(), |_| None);
503481
let mut pats = Vec::new();
@@ -615,26 +593,11 @@ impl<'a, 'b> Context<'a, 'b> {
615593
("with_placeholders", vec![pieces, fmt, args_slice])
616594
};
617595

618-
let body = self.ecx.expr_call_global(self.fmtsp, vec!(
596+
self.ecx.expr_call_global(self.fmtsp, vec!(
619597
self.ecx.ident_of("std"),
620598
self.ecx.ident_of("fmt"),
621599
self.ecx.ident_of("Arguments"),
622-
self.ecx.ident_of(fn_name)), fn_args);
623-
624-
match invocation {
625-
Call(e) => {
626-
let span = e.span;
627-
self.ecx.expr_call(span, e, vec![
628-
self.ecx.expr_addr_of(span, body)
629-
])
630-
}
631-
MethodCall(e, m) => {
632-
let span = e.span;
633-
self.ecx.expr_method_call(span, e, m, vec![
634-
self.ecx.expr_addr_of(span, body)
635-
])
636-
}
637-
}
600+
self.ecx.ident_of(fn_name)), fn_args)
638601
}
639602

640603
fn format_arg(ecx: &ExtCtxt, sp: Span,
@@ -684,24 +647,22 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp: Span,
684647
tts: &[ast::TokenTree])
685648
-> Box<base::MacResult+'cx> {
686649

687-
match parse_args(ecx, sp, false, tts) {
688-
(invocation, Some((efmt, args, order, names))) => {
689-
MacExpr::new(expand_preparsed_format_args(ecx, sp, invocation, efmt,
650+
match parse_args(ecx, sp, tts) {
651+
Some((efmt, args, order, names)) => {
652+
MacExpr::new(expand_preparsed_format_args(ecx, sp, efmt,
690653
args, order, names))
691654
}
692-
(_, None) => MacExpr::new(ecx.expr_uint(sp, 2))
655+
None => DummyResult::expr(sp)
693656
}
694657
}
695658

696-
/// Take the various parts of `format_args!(extra, efmt, args...,
697-
/// name=names...)` and construct the appropriate formatting
698-
/// expression.
659+
/// Take the various parts of `format_args!(efmt, args..., name=names...)`
660+
/// and construct the appropriate formatting expression.
699661
pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
700-
invocation: Invocation,
701662
efmt: P<ast::Expr>,
702663
args: Vec<P<ast::Expr>>,
703-
name_ordering: Vec<string::String>,
704-
names: HashMap<string::String, P<ast::Expr>>)
664+
name_ordering: Vec<String>,
665+
names: HashMap<String, P<ast::Expr>>)
705666
-> P<ast::Expr> {
706667
let arg_types = Vec::from_fn(args.len(), |_| None);
707668
let mut cx = Context {
@@ -722,8 +683,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
722683
};
723684
cx.fmtsp = efmt.span;
724685
let fmt = match expr_to_string(cx.ecx,
725-
efmt,
726-
"format argument must be a string literal.") {
686+
efmt,
687+
"format argument must be a string literal.") {
727688
Some((fmt, _)) => fmt,
728689
None => return DummyResult::raw_expr(sp)
729690
};
@@ -771,5 +732,5 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
771732
}
772733
}
773734

774-
cx.to_expr(invocation)
735+
cx.into_expr()
775736
}

0 commit comments

Comments
 (0)