From 003ce502350ed1e374b740ee2d719e500c165615 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 30 Jan 2014 00:46:37 +1100 Subject: [PATCH 1/3] std: rename fmt::Default to `Show`. This is a better name with which to have a #[deriving] mode. Decision in: https://github.com/mozilla/rust/wiki/Meeting-weekly-2014-01-28 --- src/librustdoc/html/escape.rs | 2 +- src/librustdoc/html/format.rs | 28 +++++++-------- src/librustdoc/html/layout.rs | 2 +- src/librustdoc/html/markdown.rs | 6 ++-- src/librustdoc/html/render.rs | 8 ++--- src/libstd/fmt/mod.rs | 35 ++++++++++++++----- src/libstd/io/process.rs | 2 +- src/libstd/option.rs | 2 +- src/libstd/os.rs | 2 +- src/libstd/path/mod.rs | 6 ++-- src/libstd/result.rs | 2 +- src/libsyntax/ext/format.rs | 32 ++++++++--------- src/libsyntax/parse/token.rs | 2 +- src/test/run-pass/logging-only-prints-once.rs | 2 +- 14 files changed, 75 insertions(+), 56 deletions(-) diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 13e1b8ed6de..1aaa446fc6c 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -19,7 +19,7 @@ use std::fmt; /// string when passed to a format string. pub struct Escape<'a>(&'a str); -impl<'a> fmt::Default for Escape<'a> { +impl<'a> fmt::Show for Escape<'a> { fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) { // Because the internet is always right, turns out there's not that many // characters to escape: http://stackoverflow.com/questions/7381974 diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 11a8ca0dd45..6b09072ff08 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -10,7 +10,7 @@ //! HTML formatting module //! -//! This module contains a large number of `fmt::Default` implementations for +//! This module contains a large number of `fmt::Show` implementations for //! various types in `rustdoc::clean`. These implementations all currently //! assume that HTML output is desired, although it may be possible to redesign //! them in the future to instead emit any format desired. @@ -47,7 +47,7 @@ impl PuritySpace { } } -impl fmt::Default for clean::Generics { +impl fmt::Show for clean::Generics { fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) { if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return } f.buf.write("<".as_bytes()); @@ -77,14 +77,14 @@ impl fmt::Default for clean::Generics { } } -impl fmt::Default for clean::Lifetime { +impl fmt::Show for clean::Lifetime { fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) { f.buf.write("'".as_bytes()); f.buf.write(l.get_ref().as_bytes()); } } -impl fmt::Default for clean::TyParamBound { +impl fmt::Show for clean::TyParamBound { fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) { match *bound { clean::RegionBound => { @@ -97,7 +97,7 @@ impl fmt::Default for clean::TyParamBound { } } -impl fmt::Default for clean::Path { +impl fmt::Show for clean::Path { fn fmt(path: &clean::Path, f: &mut fmt::Formatter) { if path.global { f.buf.write("::".as_bytes()) } for (i, seg) in path.segments.iter().enumerate() { @@ -269,7 +269,7 @@ fn typarams(w: &mut io::Writer, typarams: &Option<~[clean::TyParamBound]>) { } } -impl fmt::Default for clean::Type { +impl fmt::Show for clean::Type { fn fmt(g: &clean::Type, f: &mut fmt::Formatter) { match *g { clean::TyParamBinder(id) | clean::Generic(id) => { @@ -374,7 +374,7 @@ impl fmt::Default for clean::Type { } } -impl fmt::Default for clean::FnDecl { +impl fmt::Show for clean::FnDecl { fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) { write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}", args = d.inputs, @@ -383,7 +383,7 @@ impl fmt::Default for clean::FnDecl { } } -impl fmt::Default for ~[clean::Argument] { +impl fmt::Show for ~[clean::Argument] { fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) { let mut args = ~""; for (i, input) in inputs.iter().enumerate() { @@ -397,7 +397,7 @@ impl fmt::Default for ~[clean::Argument] { } } -impl<'a> fmt::Default for Method<'a> { +impl<'a> fmt::Show for Method<'a> { fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) { let Method(selfty, d) = *m; let mut args = ~""; @@ -433,7 +433,7 @@ impl<'a> fmt::Default for Method<'a> { } } -impl fmt::Default for VisSpace { +impl fmt::Show for VisSpace { fn fmt(v: &VisSpace, f: &mut fmt::Formatter) { match v.get() { Some(ast::Public) => { write!(f.buf, "pub "); } @@ -443,7 +443,7 @@ impl fmt::Default for VisSpace { } } -impl fmt::Default for PuritySpace { +impl fmt::Show for PuritySpace { fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) { match p.get() { ast::UnsafeFn => write!(f.buf, "unsafe "), @@ -453,7 +453,7 @@ impl fmt::Default for PuritySpace { } } -impl fmt::Default for clean::ViewPath { +impl fmt::Show for clean::ViewPath { fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) { match *v { clean::SimpleImport(ref name, ref src) => { @@ -478,7 +478,7 @@ impl fmt::Default for clean::ViewPath { } } -impl fmt::Default for clean::ImportSource { +impl fmt::Show for clean::ImportSource { fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) { match v.did { // FIXME: shouldn't be restricted to just local imports @@ -495,7 +495,7 @@ impl fmt::Default for clean::ImportSource { } } -impl fmt::Default for clean::ViewListIdent { +impl fmt::Show for clean::ViewListIdent { fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) { match v.source { // FIXME: shouldn't be limited to just local imports diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 20c45067f60..4565facea02 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -24,7 +24,7 @@ pub struct Page<'a> { root_path: &'a str, } -pub fn render( +pub fn render( dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T) { write!(dst, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d53adb78a30..254d65ae2f6 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -14,7 +14,7 @@ //! (bundled into the rust runtime). This module self-contains the C bindings //! and necessary legwork to render markdown, and exposes all of the //! functionality through a unit-struct, `Markdown`, which has an implementation -//! of `fmt::Default`. Example usage: +//! of `fmt::Show`. Example usage: //! //! ```rust,ignore //! use rustdoc::html::markdown::Markdown; @@ -32,7 +32,7 @@ use std::str; use std::unstable::intrinsics; use std::vec; -/// A unit struct which has the `fmt::Default` trait implemented. When +/// A unit struct which has the `fmt::Show` trait implemented. When /// formatted, this struct will emit the HTML corresponding to the rendered /// version of the contained markdown string. pub struct Markdown<'a>(&'a str); @@ -209,7 +209,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { } } -impl<'a> fmt::Default for Markdown<'a> { +impl<'a> fmt::Show for Markdown<'a> { fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) { let Markdown(md) = *md; // This is actually common enough to special-case diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86b6a5734a5..0b2c568c723 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -801,7 +801,7 @@ impl<'a> Item<'a> { } } -impl<'a> fmt::Default for Item<'a> { +impl<'a> fmt::Show for Item<'a> { fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) { match attr::find_stability(it.item.attrs.iter()) { Some(ref stability) => { @@ -990,7 +990,7 @@ fn item_module(w: &mut Writer, cx: &Context, match myitem.inner { clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => { struct Initializer<'a>(&'a str); - impl<'a> fmt::Default for Initializer<'a> { + impl<'a> fmt::Show for Initializer<'a> { fn fmt(s: &Initializer<'a>, f: &mut fmt::Formatter) { let Initializer(s) = *s; if s.len() == 0 { return; } @@ -1491,7 +1491,7 @@ fn item_typedef(w: &mut Writer, it: &clean::Item, t: &clean::Typedef) { document(w, it); } -impl<'a> fmt::Default for Sidebar<'a> { +impl<'a> fmt::Show for Sidebar<'a> { fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) { let cx = s.cx; let it = s.item; @@ -1556,7 +1556,7 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> { return map; } -impl<'a> fmt::Default for Source<'a> { +impl<'a> fmt::Show for Source<'a> { fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) { let Source(s) = *s; let lines = s.lines().len(); diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 13e6d808095..435e5568b8f 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -149,13 +149,13 @@ The current mapping of types to traits is: * `f` ⇒ `Float` * `e` ⇒ `LowerExp` * `E` ⇒ `UpperExp` -* *nothing* ⇒ `Default` +* *nothing* ⇒ `Show` What this means is that any type of argument which implements the `std::fmt::Binary` trait can then be formatted with `{:t}`. Implementations are provided for these traits for a number of primitive types by the standard library as well. If no format is specified (as in `{}` or `{:6}`), then the -format trait used is the `Default` trait. This is one of the more commonly +format trait used is the `Show` trait. This is one of the more commonly implemented traits when formatting a custom type. When implementing a format trait for your own time, you will have to implement a @@ -186,7 +186,7 @@ struct Vector2D { y: int, } -impl fmt::Default for Vector2D { +impl fmt::Show for Vector2D { fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) { // The `f.buf` value is of the type `&mut io::Writer`, which is what th // write! macro is expecting. Note that this formatting ignores the @@ -468,6 +468,7 @@ will look like `"\\{"`. */ +#[cfg(not(stage0))] use prelude::*; use cast; @@ -479,6 +480,24 @@ use repr; use util; use vec; +// SNAP b6400f9 this is just because the `prelude::*` import above +// includes default::Default, so the reexport doesn't work. +#[cfg(stage0)] +pub use Default = fmt::Show; // export required for `format!()` etc. + +#[cfg(stage0)] +use container::Container; +#[cfg(stage0)] +use iter::{Iterator, range}; +#[cfg(stage0)] +use option::{Option,Some,None}; +#[cfg(stage0)] +use vec::ImmutableVector; +#[cfg(stage0)] +use str::StrSlice; +#[cfg(stage0)] +use num::Signed; + pub mod parse; pub mod rt; @@ -542,7 +561,7 @@ pub struct Arguments<'a> { /// to this trait. There is not an explicit way of selecting this trait to be /// used for formatting, it is only if no other format is specified. #[allow(missing_doc)] -pub trait Default { fn fmt(&Self, &mut Formatter); } +pub trait Show { fn fmt(&Self, &mut Formatter); } /// Format trait for the `b` character #[allow(missing_doc)] @@ -1148,10 +1167,10 @@ impl Pointer for *mut T { fn fmt(t: &*mut T, f: &mut Formatter) { Pointer::fmt(&(*t as *T), f) } } -// Implementation of Default for various core types +// Implementation of Show for various core types macro_rules! delegate(($ty:ty to $other:ident) => { - impl<'a> Default for $ty { + impl<'a> Show for $ty { fn fmt(me: &$ty, f: &mut Formatter) { $other::fmt(me, f) } @@ -1174,10 +1193,10 @@ delegate!(char to Char) delegate!(f32 to Float) delegate!(f64 to Float) -impl Default for *T { +impl Show for *T { fn fmt(me: &*T, f: &mut Formatter) { Pointer::fmt(me, f) } } -impl Default for *mut T { +impl Show for *mut T { fn fmt(me: &*mut T, f: &mut Formatter) { Pointer::fmt(me, f) } } diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index c3fb3e97edf..6a10f24916f 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -91,7 +91,7 @@ pub enum ProcessExit { ExitSignal(int), } -impl fmt::Default for ProcessExit { +impl fmt::Show for ProcessExit { /// Format a ProcessExit enum, to nicely present the information. fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) { match *obj { diff --git a/src/libstd/option.rs b/src/libstd/option.rs index fd5f3a233e6..83cedd92a3f 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -380,7 +380,7 @@ impl Option { // Trait implementations ///////////////////////////////////////////////////////////////////////////// -impl fmt::Default for Option { +impl fmt::Show for Option { #[inline] fn fmt(s: &Option, f: &mut fmt::Formatter) { match *s { diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 457d58ae464..0ea1c7510a1 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -928,7 +928,7 @@ pub enum MapError { ErrMapViewOfFile(uint) } -impl fmt::Default for MapError { +impl fmt::Show for MapError { fn fmt(val: &MapError, out: &mut fmt::Formatter) { let str = match *val { ErrFdNotAvail => "fd not available for reading or writing", diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index c5482811a94..86f96a1075b 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -198,14 +198,14 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// Converts the Path into an owned byte vector fn into_vec(self) -> ~[u8]; - /// Returns an object that implements `fmt::Default` for printing paths + /// Returns an object that implements `Show` for printing paths /// /// This will print the equivalent of `to_display_str()` when used with a {} format parameter. fn display<'a>(&'a self) -> Display<'a, Self> { Display{ path: self, filename: false } } - /// Returns an object that implements `fmt::Default` for printing filenames + /// Returns an object that implements `Show` for printing filenames /// /// This will print the equivalent of `to_filename_display_str()` when used with a {} /// format parameter. If there is no filename, nothing will be printed. @@ -532,7 +532,7 @@ pub struct Display<'a, P> { priv filename: bool } -impl<'a, P: GenericPath> fmt::Default for Display<'a, P> { +impl<'a, P: GenericPath> fmt::Show for Display<'a, P> { fn fmt(d: &Display

, f: &mut fmt::Formatter) { d.with_str(|s| f.pad(s)) } diff --git a/src/libstd/result.rs b/src/libstd/result.rs index 4783c983d00..cc8fdeaccfe 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -206,7 +206,7 @@ impl Result { // Trait implementations ///////////////////////////////////////////////////////////////////////////// -impl fmt::Default for Result { +impl fmt::Show for Result { #[inline] fn fmt(s: &Result, f: &mut fmt::Formatter) { match *s { diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index ba1d5efdd49..535f5a5d0cd 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -704,22 +704,22 @@ impl<'a> Context<'a> { let fmt_trait = match *ty { Known(ref tyname) => { - match (*tyname).as_slice() { - "" => "Default", - "?" => "Poly", - "b" => "Bool", - "c" => "Char", - "d" | "i" => "Signed", - "e" => "LowerExp", - "E" => "UpperExp", - "f" => "Float", - "o" => "Octal", - "p" => "Pointer", - "s" => "String", - "t" => "Binary", - "u" => "Unsigned", - "x" => "LowerHex", - "X" => "UpperHex", + match tyname.as_slice() { + "" => "secret_show", + "?" => "secret_poly", + "b" => "secret_bool", + "c" => "secret_char", + "d" | "i" => "secret_signed", + "e" => "secret_lower_exp", + "E" => "secret_upper_exp", + "f" => "secret_float", + "o" => "secret_octal", + "p" => "secret_pointer", + "s" => "secret_string", + "t" => "secret_binary", + "u" => "secret_unsigned", + "x" => "secret_lower_hex", + "X" => "secret_upper_hex", _ => { self.ecx.span_err(sp, format!("unknown format trait `{}`", diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index d6edccd33a4..6d2acd3d803 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -587,7 +587,7 @@ impl BytesContainer for InternedString { } } -impl fmt::Default for InternedString { +impl fmt::Show for InternedString { fn fmt(obj: &InternedString, f: &mut fmt::Formatter) { write!(f.buf, "{}", obj.string.as_slice()); } diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs index d81b5818d66..4aef239f796 100644 --- a/src/test/run-pass/logging-only-prints-once.rs +++ b/src/test/run-pass/logging-only-prints-once.rs @@ -16,7 +16,7 @@ use std::fmt; struct Foo(Cell); -impl fmt::Default for Foo { +impl fmt::Show for Foo { fn fmt(f: &Foo, _fmt: &mut fmt::Formatter) { let Foo(ref f) = *f; assert!(f.get() == 0); From d8b6919d4fcd1b69494278bb4472e095e2cd52f3 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 31 Jan 2014 21:32:39 +1100 Subject: [PATCH 2/3] std::fmt: prepare to convert the formatting traits to methods, and work around the lack of UFCS. The further work is pending a snapshot, to avoid putting #[cfg(stage0)] attributes on all the traits and duplicating them. --- src/libstd/fmt/mod.rs | 35 +++++++++++++++++++++++++++++++++++ src/libsyntax/ext/format.rs | 12 +++++------- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 435e5568b8f..14bf0206c28 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -606,6 +606,41 @@ pub trait LowerExp { fn fmt(&Self, &mut Formatter); } #[allow(missing_doc)] pub trait UpperExp { fn fmt(&Self, &mut Formatter); } +// FIXME #11938 - UFCS would make us able call the above methods +// directly Show::show(x, fmt). + +// FIXME(huonw's WIP): this is a intermediate state waiting for a +// snapshot (at the time of writing we're at 2014-01-20 b6400f9), to +// be able to make the `fmt` functions into normal methods and have +// `format!()` still work. +macro_rules! uniform_fn_call_workaround { + ($( $name: ident, $trait_: ident; )*) => { + $( + #[doc(hidden)] + pub fn $name(x: &T, fmt: &mut Formatter) { + $trait_::fmt(x, fmt) + } + )* + } +} +uniform_fn_call_workaround! { + secret_show, Show; + secret_bool, Bool; + secret_char, Char; + secret_signed, Signed; + secret_unsigned, Unsigned; + secret_octal, Octal; + secret_binary, Binary; + secret_lower_hex, LowerHex; + secret_upper_hex, UpperHex; + secret_string, String; + secret_poly, Poly; + secret_pointer, Pointer; + secret_float, Float; + secret_lower_exp, LowerExp; + secret_upper_exp, UpperExp; +} + /// The `write` function takes an output stream, a precompiled format string, /// and a list of arguments. The arguments will be formatted according to the /// specified format string into the output stream provided. diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 535f5a5d0cd..1893cc0c722 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -702,7 +702,7 @@ impl<'a> Context<'a> { Named(ref s) => self.name_types.get(s) }; - let fmt_trait = match *ty { + let fmt_fn = match *ty { Known(ref tyname) => { match tyname.as_slice() { "" => "secret_show", @@ -721,10 +721,9 @@ impl<'a> Context<'a> { "x" => "secret_lower_hex", "X" => "secret_upper_hex", _ => { - self.ecx.span_err(sp, - format!("unknown format trait `{}`", - *tyname)); - "Dummy" + self.ecx.span_err(sp, format!("unknown format trait `{}`", + *tyname)); + "dummy" } } } @@ -747,8 +746,7 @@ impl<'a> Context<'a> { let format_fn = self.ecx.path_global(sp, ~[ self.ecx.ident_of("std"), self.ecx.ident_of("fmt"), - self.ecx.ident_of(fmt_trait), - self.ecx.ident_of("fmt"), + self.ecx.ident_of(fmt_fn), ]); self.ecx.expr_call_global(sp, ~[ self.ecx.ident_of("std"), From c19a7b68577f28547bdfb357798d05163ccb6824 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 2 Feb 2014 16:22:54 +1100 Subject: [PATCH 3/3] Remove the SNAP line to work around #11985. --- src/libstd/fmt/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 14bf0206c28..a17a030f4f7 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -480,8 +480,8 @@ use repr; use util; use vec; -// SNAP b6400f9 this is just because the `prelude::*` import above -// includes default::Default, so the reexport doesn't work. +// NOTE this is just because the `prelude::*` import above includes +// default::Default, so the reexport doesn't work. #[cfg(stage0)] pub use Default = fmt::Show; // export required for `format!()` etc.