about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-12 07:30:44 +0000
committerbors <bors@rust-lang.org>2015-03-12 07:30:44 +0000
commit49f7550a25722fbdb779eef80afa85f6d802f7e8 (patch)
treeea61e689eb6a17ae4766f873f095c66b2bdfa5f5 /src/libsyntax
parent8715a65496b557798a9ff346194991aea3581f4d (diff)
parent905a611b94d1fd50f15cd06f27cd44fd4dacb131 (diff)
downloadrust-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.rs2
-rw-r--r--src/libsyntax/ext/deriving/show.rs102
-rw-r--r--src/libsyntax/ext/expand.rs2
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,