summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcore/fmt/builders.rs18
-rw-r--r--src/libcore/fmt/mod.rs6
-rw-r--r--src/libcoretest/fmt/builders.rs10
-rw-r--r--src/libsyntax/ext/deriving/show.rs102
-rw-r--r--src/libsyntax/ext/expand.rs2
5 files changed, 74 insertions, 64 deletions
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index d96da4cafb0..37165cdc5ed 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -1,3 +1,13 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
 use prelude::*;
 use fmt::{self, Write, FlagV1};
 
@@ -69,6 +79,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
         self
     }
 
+    #[inline(never)]
     fn field_inner(&mut self, name: &str, value: &fmt::Debug) {
         self.result = self.result.and_then(|_| {
             let prefix = if self.has_fields {
@@ -97,6 +108,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
         self.result
     }
 
+    #[inline(never)]
     fn finish_inner(&mut self) {
         if self.has_fields {
             self.result = self.result.and_then(|_| {
@@ -142,6 +154,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
         self
     }
 
+    #[inline(never)]
     fn field_inner(&mut self, value: &fmt::Debug) {
         self.result = self.result.and_then(|_| {
             let (prefix, space) = if self.has_fields {
@@ -170,6 +183,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
         self.result
     }
 
+    #[inline(never)]
     fn finish_inner(&mut self) {
         if self.has_fields {
             self.result = self.result.and_then(|_| {
@@ -215,6 +229,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
         self
     }
 
+    #[inline(never)]
     fn entry_inner(&mut self, entry: &fmt::Debug) {
         self.result = self.result.and_then(|_| {
             let prefix = if self.has_fields {
@@ -243,6 +258,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
         self.result
     }
 
+    #[inline(never)]
     fn finish_inner(&mut self) {
         self.result = self.result.and_then(|_| {
             let end = match (self.has_fields, self.is_pretty()) {
@@ -287,6 +303,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
         self
     }
 
+    #[inline(never)]
     fn entry_inner(&mut self, key: &fmt::Debug, value: &fmt::Debug) {
         self.result = self.result.and_then(|_| {
             let prefix = if self.has_fields {
@@ -315,6 +332,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
         self.result
     }
 
+    #[inline(never)]
     fn finish_inner(&mut self) {
         self.result = self.result.and_then(|_| {
             let end = match (self.has_fields, self.is_pretty()) {
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 572d613f192..741cf7b47fa 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -644,6 +644,7 @@ impl<'a> Formatter<'a> {
     /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() });
     /// ```
     #[unstable(feature = "core", reason = "method was just created")]
+    #[inline]
     pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> {
         builders::debug_struct_new(self, name)
     }
@@ -671,6 +672,7 @@ impl<'a> Formatter<'a> {
     /// println!("{:?}", Foo(10, "Hello World".to_string()));
     /// ```
     #[unstable(feature = "core", reason = "method was just created")]
+    #[inline]
     pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> {
         builders::debug_tuple_new(self, name)
     }
@@ -699,6 +701,7 @@ impl<'a> Formatter<'a> {
     /// println!("{:?}", Foo(vec![10, 11]));
     /// ```
     #[unstable(feature = "core", reason = "method was just created")]
+    #[inline]
     pub fn debug_set<'b>(&'b mut self, name: &str) -> DebugSet<'b, 'a> {
         builders::debug_set_new(self, name)
     }
@@ -724,9 +727,10 @@ impl<'a> Formatter<'a> {
     /// }
     ///
     /// // prints "Foo { "A": 10, "B": 11 }"
-    /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)));
+    /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)]));
     /// ```
     #[unstable(feature = "core", reason = "method was just created")]
+    #[inline]
     pub fn debug_map<'b>(&'b mut self, name: &str) -> DebugMap<'b, 'a> {
         builders::debug_map_new(self, name)
     }
diff --git a/src/libcoretest/fmt/builders.rs b/src/libcoretest/fmt/builders.rs
index 84076b349d2..b2fbc90be59 100644
--- a/src/libcoretest/fmt/builders.rs
+++ b/src/libcoretest/fmt/builders.rs
@@ -1,3 +1,13 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
 mod debug_struct {
     use std::fmt;
 
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,