diff options
| author | bors <bors@rust-lang.org> | 2015-03-12 07:30:44 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-03-12 07:30:44 +0000 |
| commit | 49f7550a25722fbdb779eef80afa85f6d802f7e8 (patch) | |
| tree | ea61e689eb6a17ae4766f873f095c66b2bdfa5f5 /src/libsyntax | |
| parent | 8715a65496b557798a9ff346194991aea3581f4d (diff) | |
| parent | 905a611b94d1fd50f15cd06f27cd44fd4dacb131 (diff) | |
| download | rust-49f7550a25722fbdb779eef80afa85f6d802f7e8.tar.gz rust-49f7550a25722fbdb779eef80afa85f6d802f7e8.zip | |
Auto merge of #23162 - sfackler:debug-builders, r=alexcrichton
I've made some minor changes from the implementation attached to the RFC to try to minimize codegen. The methods now take `&Debug` trait objects rather than being parameterized and there are inlined stub methods that call to non-inlined methods to do the work. r? @alexcrichton cc @huonw for the `derive(Debug)` changes.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/codemap.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/show.rs | 102 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 2 |
3 files changed, 42 insertions, 64 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 7d2d4e53fe9..70aab26092c 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -848,7 +848,7 @@ impl CodeMap { let span_comes_from_this_expansion = info.callee.span.map_or(span == info.call_site, |mac_span| { - mac_span.lo <= span.lo && span.hi < mac_span.hi + mac_span.lo <= span.lo && span.hi <= mac_span.hi }); debug!("span_allows_unstable: from this expansion? {}, allows unstable? {}", diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index ce89c541fd4..ae9a4020060 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -11,7 +11,6 @@ use ast; use ast::{MetaItem, Item, Expr,}; use codemap::Span; -use ext::format; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; @@ -19,8 +18,6 @@ use ext::deriving::generic::ty::*; use parse::token; use ptr::P; -use std::collections::HashMap; - pub fn expand_deriving_show<F>(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, @@ -56,14 +53,12 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt, trait_def.expand(cx, mitem, item, push) } -/// We construct a format string and then defer to std::fmt, since that -/// knows what's up with formatting and so on. +/// We use the debug builders to do the heavy lifting here fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> { - // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {}, - // <field>: {}, ... }` based on the "shape". - // - // Easy start: they all start with the name. + // build fmt.debug_struct(<name>).field(<fieldname>, &<fieldval>)....build() + // or fmt.debug_tuple(<name>).field(&<fieldval>)....build() + // based on the "shape". let name = match *substr.fields { Struct(_) => substr.type_ident, EnumMatching(_, v, _) => v.node.name, @@ -72,70 +67,53 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, } }; - let mut format_string = String::from_str(&token::get_ident(name)); - // the internal fields we're actually formatting - let mut exprs = Vec::new(); + // We want to make sure we have the expn_id set so that we can use unstable methods + let span = Span { expn_id: cx.backtrace(), .. span }; + let name = cx.expr_lit(span, ast::Lit_::LitStr(token::get_ident(name), + ast::StrStyle::CookedStr)); + let mut expr = substr.nonself_args[0].clone(); - // Getting harder... making the format string: match *substr.fields { - // unit struct/nullary variant: no work necessary! - Struct(ref fields) if fields.len() == 0 => {} - EnumMatching(_, _, ref fields) if fields.len() == 0 => {} - Struct(ref fields) | EnumMatching(_, _, ref fields) => { - if fields[0].name.is_none() { + if fields.is_empty() || fields[0].name.is_none() { // tuple struct/"normal" variant - - format_string.push_str("("); - - for (i, field) in fields.iter().enumerate() { - if i != 0 { format_string.push_str(", "); } - - format_string.push_str("{:?}"); - - exprs.push(field.self_.clone()); + expr = cx.expr_method_call(span, + expr, + token::str_to_ident("debug_tuple"), + vec![name]); + + for field in fields { + expr = cx.expr_method_call(span, + expr, + token::str_to_ident("field"), + vec![cx.expr_addr_of(field.span, + field.self_.clone())]); } - - format_string.push_str(")"); } else { // normal struct/struct variant - - format_string.push_str(" {{"); - - for (i, field) in fields.iter().enumerate() { - if i != 0 { format_string.push_str(","); } - - let name = token::get_ident(field.name.unwrap()); - format_string.push_str(" "); - format_string.push_str(&name); - format_string.push_str(": {:?}"); - - exprs.push(field.self_.clone()); + expr = cx.expr_method_call(span, + expr, + token::str_to_ident("debug_struct"), + vec![name]); + + for field in fields { + let name = cx.expr_lit(field.span, ast::Lit_::LitStr( + token::get_ident(field.name.clone().unwrap()), + ast::StrStyle::CookedStr)); + expr = cx.expr_method_call(span, + expr, + token::str_to_ident("field"), + vec![name, + cx.expr_addr_of(field.span, + field.self_.clone())]); } - - format_string.push_str(" }}"); } } _ => unreachable!() } - // AST construction! - // we're basically calling - // - // format_arg_method!(fmt, write_fmt, "<format_string>", exprs...) - // - // but doing it directly via ext::format. - let formatter = substr.nonself_args[0].clone(); - - let meth = cx.ident_of("write_fmt"); - let s = token::intern_and_get_ident(&format_string[..]); - let format_string = cx.expr_str(span, s); - - // phew, not our responsibility any more! - - let args = vec![ - format::expand_preparsed_format_args(cx, span, format_string, - exprs, vec![], HashMap::new()) - ]; - cx.expr_method_call(span, formatter, meth, args) + cx.expr_method_call(span, + expr, + token::str_to_ident("finish"), + vec![]) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 98c7aefcd8a..6883395933e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1121,7 +1121,7 @@ fn expand_annotatable(a: Annotatable, callee: NameAndSpan { name: mname.to_string(), format: MacroAttribute, - span: None, + span: Some(attr.span), // attributes can do whatever they like, // for now. allow_internal_unstable: true, |
