Skip to content

Commit 778ce62

Browse files
committed
format_args: allow omission of format string
A default format string of Poly {:?} is generated to match the number of passed arguments. This propagates to all fmt macros, such as println!, debug!, format!, write!, etc. Example: println!("{:?}", value); => println!(value); fixes rust-lang#12015
1 parent 62d7d00 commit 778ce62

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

src/libsyntax/ext/format.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,20 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
782782
}
783783
}
784784

785+
/// Try to match a string literal, and if not found, emit a note. No big deal.
786+
fn try_expr_literal(cx: &ExtCtxt, expr: @ast::Expr, note_msg: &str)
787+
-> Option<~str> {
788+
789+
match expr.node {
790+
ast::ExprLit(l) => match l.node {
791+
ast::LitStr(ref s, _) => return Some(s.get().to_owned()),
792+
_ => cx.span_note(l.span, note_msg)
793+
},
794+
_ => cx.span_note(expr.span, note_msg)
795+
}
796+
None
797+
}
798+
785799
/// Take the various parts of `format_args!(extra, efmt, args...,
786800
/// name=names...)` and construct the appropriate formatting
787801
/// expression.
@@ -807,14 +821,22 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
807821
// Be sure to recursively expand macros just in case the format string uses
808822
// a macro to build the format expression.
809823
let expr = cx.ecx.expand_expr(efmt);
810-
let fmt = match expr_to_str(cx.ecx,
811-
expr,
812-
"format argument must be a string literal.") {
813-
Some((fmt, _)) => fmt,
814-
None => return efmt
824+
let fmt = match try_expr_literal(cx.ecx,
825+
expr,
826+
"format string literal missing, using default") {
827+
Some(fmt) => fmt,
828+
None => {
829+
// push arg back into args lists
830+
cx.args.unshift(expr);
831+
cx.arg_types.unshift(None);
832+
let mut parts = ~[];
833+
let form = ~"{:?}";
834+
parts.grow(cx.args.len(), &form);
835+
parts.connect(" ")
836+
}
815837
};
816838

817-
let mut parser = parse::Parser::new(fmt.get());
839+
let mut parser = parse::Parser::new(fmt);
818840
loop {
819841
match parser.next() {
820842
Some(piece) => {

src/test/run-pass/ifmt.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ pub fn main() {
4848
t!(format!("hello"), "hello");
4949
t!(format!("hello \\{"), "hello {");
5050

51+
// No format string uses default poly formatters
52+
t!(format!(1), "1");
53+
t!(format!(1, 2), "1 2");
54+
t!(format!(1, "foo", 2, true), "1 \"foo\" 2 true");
55+
5156
// default formatters should work
5257
t!(format!("{}", 1i), "1");
5358
t!(format!("{}", 1i8), "1");

0 commit comments

Comments
 (0)