From 4037f2a368edd75c561bc6f3d8c6f0d644bc4180 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 26 Mar 2015 22:42:29 -0700 Subject: [PATCH] Update debug helpers and add list builder The collections debug helpers no longer prefix output with the collection name, in line with the current conventions for Debug implementations. Implementations that want to preserve the current behavior can simply add a `try!(write!(fmt, "TypeName "));` at the beginning of the `fmt` method. [breaking-change] --- src/libcollections/btree/map.rs | 11 +- src/libcollections/btree/set.rs | 11 +- src/libcollections/lib.rs | 1 + src/libcollections/linked_list.rs | 11 +- src/libcore/fmt/builders.rs | 142 ++++++++++++++++---------- src/libcore/fmt/mod.rs | 52 ++++++++-- src/libcoretest/fmt/builders.rs | 157 +++++++++++++++++++++++------ src/libstd/collections/hash/map.rs | 11 +- src/libstd/collections/hash/set.rs | 11 +- src/libstd/lib.rs | 1 + 10 files changed, 277 insertions(+), 131 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index d2b45f4b049..93978e31de5 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -904,14 +904,11 @@ impl Ord for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}: {:?}", *k, *v)); + let mut builder = f.debug_map(); + for (k, v) in self { + builder = builder.entry(k, v); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 08ee5801482..db0cdd30b1b 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -628,14 +628,11 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeSet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, x) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}", *x)); + let mut builder = f.debug_set(); + for x in self { + builder = builder.entry(x); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index f774c1505b8..c769b3df37f 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -40,6 +40,7 @@ #![feature(str_char)] #![feature(convert)] #![feature(slice_patterns)] +#![feature(debug_builders)] #![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))] #![cfg_attr(test, allow(deprecated))] // rand diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 908c78a17f4..56c880ca6e2 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -927,14 +927,11 @@ impl Clone for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "[")); - - for (i, e) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}", *e)); + let mut builder = f.debug_list(); + for e in self { + builder = builder.entry(e); } - - write!(f, "]") + builder.finish() } } diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index 07f029cc15e..f61a7f2d30c 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -177,22 +177,54 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> { } } -/// A struct to help with `fmt::Debug` implementations. -/// -/// Constructed by the `Formatter::debug_set` method. -#[must_use] -pub struct DebugSet<'a, 'b: 'a> { +struct DebugInner<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, has_fields: bool, } -pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugSet<'a, 'b> { - let result = write!(fmt, "{} {{", name); +impl<'a, 'b: 'a> DebugInner<'a, 'b> { + fn entry(&mut self, entry: &fmt::Debug) { + self.result = self.result.and_then(|_| { + if self.is_pretty() { + let mut writer = PadAdapter::new(self.fmt); + let prefix = if self.has_fields { "," } else { "" }; + fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry)) + } else { + let prefix = if self.has_fields { ", " } else { "" }; + write!(self.fmt, "{}{:?}", prefix, entry) + } + }); + + self.has_fields = true; + } + + pub fn finish(&mut self) { + let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" }; + self.result = self.result.and_then(|_| self.fmt.write_str(prefix)); + } + + fn is_pretty(&self) -> bool { + self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_set` method. +#[must_use] +pub struct DebugSet<'a, 'b: 'a> { + inner: DebugInner<'a, 'b>, +} + +pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> { + let result = write!(fmt, "{{"); DebugSet { - fmt: fmt, - result: result, - has_fields: false, + inner: DebugInner { + fmt: fmt, + result: result, + has_fields: false, + } } } @@ -200,41 +232,52 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// Adds a new entry to the set output. #[unstable(feature = "debug_builders", reason = "method was just created")] pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> { - self.result = self.result.and_then(|_| { - let prefix = if self.has_fields { - "," - } else { - "" - }; - - if self.is_pretty() { - let mut writer = PadAdapter::new(self.fmt); - fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry)) - } else { - write!(self.fmt, "{} {:?}", prefix, entry) - } - }); - - self.has_fields = true; + self.inner.entry(entry); self } /// Consumes the `DebugSet`, finishing output and returning any error /// encountered. #[unstable(feature = "debug_builders", reason = "method was just created")] - pub fn finish(self) -> fmt::Result { - self.result.and_then(|_| { - let end = match (self.has_fields, self.is_pretty()) { - (false, _) => "}", - (true, false) => " }", - (true, true) => "\n}", - }; - self.fmt.write_str(end) - }) + pub fn finish(mut self) -> fmt::Result { + self.inner.finish(); + self.inner.result.and_then(|_| self.inner.fmt.write_str("}")) + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_list` method. +#[must_use] +pub struct DebugList<'a, 'b: 'a> { + inner: DebugInner<'a, 'b>, +} + +pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> { + let result = write!(fmt, "["); + DebugList { + inner: DebugInner { + fmt: fmt, + result: result, + has_fields: false, + } + } +} + +impl<'a, 'b: 'a> DebugList<'a, 'b> { + /// Adds a new entry to the set output. + #[unstable(feature = "debug_builders", reason = "method was just created")] + pub fn entry(mut self, entry: &fmt::Debug) -> DebugList<'a, 'b> { + self.inner.entry(entry); + self } - fn is_pretty(&self) -> bool { - self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + /// Consumes the `DebugSet`, finishing output and returning any error + /// encountered. + #[unstable(feature = "debug_builders", reason = "method was just created")] + pub fn finish(mut self) -> fmt::Result { + self.inner.finish(); + self.inner.result.and_then(|_| self.inner.fmt.write_str("]")) } } @@ -248,8 +291,8 @@ pub struct DebugMap<'a, 'b: 'a> { has_fields: bool, } -pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugMap<'a, 'b> { - let result = write!(fmt, "{} {{", name); +pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { + let result = write!(fmt, "{{"); DebugMap { fmt: fmt, result: result, @@ -262,22 +305,17 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { #[unstable(feature = "debug_builders", reason = "method was just created")] pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> { self.result = self.result.and_then(|_| { - let prefix = if self.has_fields { - "," - } else { - "" - }; - if self.is_pretty() { let mut writer = PadAdapter::new(self.fmt); + let prefix = if self.has_fields { "," } else { "" }; fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value)) } else { - write!(self.fmt, "{} {:?}: {:?}", prefix, key, value) + let prefix = if self.has_fields { ", " } else { "" }; + write!(self.fmt, "{}{:?}: {:?}", prefix, key, value) } }); self.has_fields = true; - self } @@ -285,14 +323,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// encountered. #[unstable(feature = "debug_builders", reason = "method was just created")] pub fn finish(self) -> fmt::Result { - self.result.and_then(|_| { - let end = match (self.has_fields, self.is_pretty()) { - (false, _) => "}", - (true, false) => " }", - (true, true) => "\n}", - }; - self.fmt.write_str(end) - }) + let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" }; + self.result.and_then(|_| write!(self.fmt, "{}}}", prefix)) } fn is_pretty(&self) -> bool { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index aa0d0a1539a..856e7569f1c 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -32,7 +32,7 @@ pub use self::num::radix; pub use self::num::Radix; pub use self::num::RadixFmt; -pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugMap}; +pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap}; mod num; mod float; @@ -644,7 +644,7 @@ impl<'a> Formatter<'a> { /// // prints "Foo { bar: 10, baz: "Hello World" }" /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", 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) @@ -673,12 +673,42 @@ impl<'a> Formatter<'a> { /// // prints "Foo(10, "Hello World")" /// println!("{:?}", Foo(10, "Hello World".to_string())); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", 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) } + /// Creates a `DebugList` builder designed to assist with creation of + /// `fmt::Debug` implementations for list-like structures. + /// + /// # Examples + /// + /// ```rust + /// # #![feature(debug_builders, core)] + /// use std::fmt; + /// + /// struct Foo(Vec); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// let mut builder = fmt.debug_list(); + /// for i in &self.0 { + /// builder = builder.entry(i); + /// } + /// builder.finish() + /// } + /// } + /// + /// // prints "Foo { 10, 11 }" + /// println!("{:?}", Foo(vec![10, 11])); + /// ``` + #[unstable(feature = "debug_builders", reason = "method was just created")] + #[inline] + pub fn debug_list<'b>(&'b mut self) -> DebugList<'b, 'a> { + builders::debug_list_new(self) + } + /// Creates a `DebugSet` builder designed to assist with creation of /// `fmt::Debug` implementations for set-like structures. /// @@ -692,7 +722,7 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// let mut builder = fmt.debug_set("Foo"); + /// let mut builder = fmt.debug_set(); /// for i in &self.0 { /// builder = builder.entry(i); /// } @@ -703,10 +733,10 @@ impl<'a> Formatter<'a> { /// // prints "Foo { 10, 11 }" /// println!("{:?}", Foo(vec![10, 11])); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", 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) + pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> { + builders::debug_set_new(self) } /// Creates a `DebugMap` builder designed to assist with creation of @@ -722,7 +752,7 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// let mut builder = fmt.debug_map("Foo"); + /// let mut builder = fmt.debug_map(); /// for &(ref key, ref value) in &self.0 { /// builder = builder.entry(key, value); /// } @@ -733,10 +763,10 @@ impl<'a> Formatter<'a> { /// // prints "Foo { "A": 10, "B": 11 }" /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", 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) + pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> { + builders::debug_map_new(self) } } diff --git a/src/libcoretest/fmt/builders.rs b/src/libcoretest/fmt/builders.rs index b2fbc90be59..885ee3f9c3b 100644 --- a/src/libcoretest/fmt/builders.rs +++ b/src/libcoretest/fmt/builders.rs @@ -211,12 +211,12 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo").finish() + fmt.debug_map().finish() } } - assert_eq!("Foo {}", format!("{:?}", Foo)); - assert_eq!("Foo {}", format!("{:#?}", Foo)); + assert_eq!("{}", format!("{:?}", Foo)); + assert_eq!("{}", format!("{:#?}", Foo)); } #[test] @@ -225,15 +225,15 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo") + fmt.debug_map() .entry(&"bar", &true) .finish() } } - assert_eq!("Foo { \"bar\": true }", format!("{:?}", Foo)); + assert_eq!("{\"bar\": true}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ \"bar\": true }", format!("{:#?}", Foo)); @@ -245,16 +245,16 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo") + fmt.debug_map() .entry(&"bar", &true) .entry(&10i32, &format_args!("{}/{}", 10i32, 20i32)) .finish() } } - assert_eq!("Foo { \"bar\": true, 10: 10/20 }", format!("{:?}", Foo)); + assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ \"bar\": true, 10: 10/20 }", @@ -267,7 +267,7 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo") + fmt.debug_map() .entry(&"bar", &true) .entry(&10i32, &format_args!("{}/{}", 10i32, 20i32)) .finish() @@ -278,23 +278,23 @@ mod debug_map { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Bar") + fmt.debug_map() .entry(&"foo", &Foo) .entry(&Foo, &"world") .finish() } } - assert_eq!("Bar { \"foo\": Foo { \"bar\": true, 10: 10/20 }, \ - Foo { \"bar\": true, 10: 10/20 }: \"world\" }", + assert_eq!("{\"foo\": {\"bar\": true, 10: 10/20}, \ + {\"bar\": true, 10: 10/20}: \"world\"}", format!("{:?}", Bar)); assert_eq!( -"Bar { - \"foo\": Foo { +"{ + \"foo\": { \"bar\": true, 10: 10/20 }, - Foo { + { \"bar\": true, 10: 10/20 }: \"world\" @@ -312,12 +312,12 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo").finish() + fmt.debug_set().finish() } } - assert_eq!("Foo {}", format!("{:?}", Foo)); - assert_eq!("Foo {}", format!("{:#?}", Foo)); + assert_eq!("{}", format!("{:?}", Foo)); + assert_eq!("{}", format!("{:#?}", Foo)); } #[test] @@ -326,15 +326,15 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo") + fmt.debug_set() .entry(&true) .finish() } } - assert_eq!("Foo { true }", format!("{:?}", Foo)); + assert_eq!("{true}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ true }", format!("{:#?}", Foo)); @@ -346,16 +346,16 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo") + fmt.debug_set() .entry(&true) .entry(&format_args!("{}/{}", 10i32, 20i32)) .finish() } } - assert_eq!("Foo { true, 10/20 }", format!("{:?}", Foo)); + assert_eq!("{true, 10/20}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ true, 10/20 }", @@ -368,7 +368,7 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo") + fmt.debug_set() .entry(&true) .entry(&format_args!("{}/{}", 10i32, 20i32)) .finish() @@ -379,18 +379,18 @@ mod debug_set { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Bar") + fmt.debug_set() .entry(&Foo) .entry(&"world") .finish() } } - assert_eq!("Bar { Foo { true, 10/20 }, \"world\" }", + assert_eq!("{{true, 10/20}, \"world\"}", format!("{:?}", Bar)); assert_eq!( -"Bar { - Foo { +"{ + { true, 10/20 }, @@ -399,3 +399,100 @@ mod debug_set { format!("{:#?}", Bar)); } } + +mod debug_list { + use std::fmt; + + #[test] + fn test_empty() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list().finish() + } + } + + assert_eq!("[]", format!("{:?}", Foo)); + assert_eq!("[]", format!("{:#?}", Foo)); + } + + #[test] + fn test_single() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&true) + .finish() + } + } + + assert_eq!("[true]", format!("{:?}", Foo)); + assert_eq!( +"[ + true +]", + format!("{:#?}", Foo)); + } + + #[test] + fn test_multiple() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&true) + .entry(&format_args!("{}/{}", 10i32, 20i32)) + .finish() + } + } + + assert_eq!("[true, 10/20]", format!("{:?}", Foo)); + assert_eq!( +"[ + true, + 10/20 +]", + format!("{:#?}", Foo)); + } + + #[test] + fn test_nested() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&true) + .entry(&format_args!("{}/{}", 10i32, 20i32)) + .finish() + } + } + + struct Bar; + + impl fmt::Debug for Bar { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&Foo) + .entry(&"world") + .finish() + } + } + + assert_eq!("[[true, 10/20], \"world\"]", + format!("{:?}", Bar)); + assert_eq!( +"[ + [ + true, + 10/20 + ], + \"world\" +]", + format!("{:#?}", Bar)); + } +} diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f9e1cb877b6..fd62729cd8f 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1226,14 +1226,11 @@ impl Debug for HashMap where K: Eq + Hash + Debug, V: Debug, S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}: {:?}", *k, *v)); + let mut builder = f.debug_map(); + for (k, v) in self.iter() { + builder = builder.entry(k, v); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 0933b4f662a..44c3d8262a7 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -614,14 +614,11 @@ impl fmt::Debug for HashSet S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, x) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}", *x)); + let mut builder = f.debug_set(); + for x in self { + builder = builder.entry(x); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 5f5f2fed567..b7cb8f9ed50 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -128,6 +128,7 @@ #![feature(into_cow)] #![feature(slice_patterns)] #![feature(std_misc)] +#![feature(debug_builders)] #![cfg_attr(test, feature(test, rustc_private, std_misc))] // Don't link to std. We are std.