diff --git a/src/doc/rust.md b/src/doc/rust.md index 21c2e5eefec..bae8f562af5 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -1969,13 +1969,14 @@ impl<T: Eq> Eq for Foo<T> { Supported traits for `deriving` are: * Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`. -* Serialization: `Encodable`, `Decodable`. These require `extra`. +* Serialization: `Encodable`, `Decodable`. These require `serialize`. * `Clone` and `DeepClone`, to perform (deep) copies. * `IterBytes`, to iterate over the bytes in a data type. * `Rand`, to create a random instance of a data type. * `Default`, to create an empty instance of a data type. * `Zero`, to create an zero instance of a numeric data type. -* `FromPrimitive`, to create an instance from a numeric primitve. +* `FromPrimitive`, to create an instance from a numeric primitive. +* `Show`, to format a value using the `{}` formatter. ### Stability One can indicate the stability of an API using the following attributes: diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index 5d60b90a8f3..a5426c20619 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -2523,7 +2523,7 @@ enum ABC { A, B, C } The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`, -`IterBytes`, `Rand`, `Default`, `Zero`, and `ToStr`. +`IterBytes`, `Rand`, `Default`, `Zero`, `FromPrimitive` and `Show`. # Crates and the module system diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index a3f057c04b0..7acaa761bb2 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -118,7 +118,8 @@ traits = { for (trait, supers, errs) in [('Rand', [], 1), ('Clone', [], 1), ('DeepClone', ['Clone'], 1), ('Eq', [], 2), ('Ord', [], 8), - ('TotalEq', [], 1), ('TotalOrd', ['TotalEq'], 1)]: + ('TotalEq', [], 1), ('TotalOrd', ['TotalEq'], 1), + ('Show', [], 1)]: traits[trait] = (ALL, supers, errs) for (trait, (types, super_traits, error_count)) in traits.items(): diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 82850dffa2b..153de66363b 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -20,10 +20,10 @@ use std::fmt; pub struct Escape<'a>(&'a str); impl<'a> fmt::Show for Escape<'a> { - fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { // Because the internet is always right, turns out there's not that many // characters to escape: http://stackoverflow.com/questions/7381974 - let Escape(s) = *s; + let Escape(s) = *self; let pile_o_bits = s.as_slice(); let mut last = 0; for (i, ch) in s.bytes().enumerate() { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index a1a6a173ede..024d010f0b9 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -48,23 +48,23 @@ impl PuritySpace { } impl fmt::Show for clean::Generics { - fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) -> fmt::Result { - if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return Ok(()) } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) } if_ok!(f.buf.write("<".as_bytes())); - for (i, life) in g.lifetimes.iter().enumerate() { + for (i, life) in self.lifetimes.iter().enumerate() { if i > 0 { if_ok!(f.buf.write(", ".as_bytes())); } if_ok!(write!(f.buf, "{}", *life)); } - if g.type_params.len() > 0 { - if g.lifetimes.len() > 0 { + if self.type_params.len() > 0 { + if self.lifetimes.len() > 0 { if_ok!(f.buf.write(", ".as_bytes())); } - for (i, tp) in g.type_params.iter().enumerate() { + for (i, tp) in self.type_params.iter().enumerate() { if i > 0 { if_ok!(f.buf.write(", ".as_bytes())) } @@ -87,16 +87,16 @@ impl fmt::Show for clean::Generics { } impl fmt::Show for clean::Lifetime { - fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if_ok!(f.buf.write("'".as_bytes())); - if_ok!(f.buf.write(l.get_ref().as_bytes())); + if_ok!(f.buf.write(self.get_ref().as_bytes())); Ok(()) } } impl fmt::Show for clean::TyParamBound { - fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) -> fmt::Result { - match *bound { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { clean::RegionBound => { f.buf.write("'static".as_bytes()) } @@ -108,11 +108,11 @@ impl fmt::Show for clean::TyParamBound { } impl fmt::Show for clean::Path { - fn fmt(path: &clean::Path, f: &mut fmt::Formatter) -> fmt::Result { - if path.global { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.global { if_ok!(f.buf.write("::".as_bytes())) } - for (i, seg) in path.segments.iter().enumerate() { + for (i, seg) in self.segments.iter().enumerate() { if i > 0 { if_ok!(f.buf.write("::".as_bytes())) } @@ -297,8 +297,8 @@ fn typarams(w: &mut io::Writer, } impl fmt::Show for clean::Type { - fn fmt(g: &clean::Type, f: &mut fmt::Formatter) -> fmt::Result { - match *g { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { clean::TyParamBinder(id) | clean::Generic(id) => { local_data::get(cache_key, |cache| { let m = cache.unwrap().get(); @@ -405,18 +405,18 @@ impl fmt::Show for clean::Type { } impl fmt::Show for clean::FnDecl { - fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}", - args = d.inputs, - arrow = match d.output { clean::Unit => "no", _ => "yes" }, - ret = d.output) + args = self.inputs, + arrow = match self.output { clean::Unit => "no", _ => "yes" }, + ret = self.output) } } impl fmt::Show for ~[clean::Argument] { - fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut args = ~""; - for (i, input) in inputs.iter().enumerate() { + for (i, input) in self.iter().enumerate() { if i > 0 { args.push_str(", "); } if input.name.len() > 0 { args.push_str(format!("{}: ", input.name)); @@ -428,8 +428,8 @@ impl fmt::Show for ~[clean::Argument] { } impl<'a> fmt::Show for Method<'a> { - fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) -> fmt::Result { - let Method(selfty, d) = *m; + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let Method(selfty, d) = *self; let mut args = ~""; match *selfty { clean::SelfStatic => {}, @@ -463,8 +463,8 @@ impl<'a> fmt::Show for Method<'a> { } impl fmt::Show for VisSpace { - fn fmt(v: &VisSpace, f: &mut fmt::Formatter) -> fmt::Result { - match v.get() { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { Some(ast::Public) => write!(f.buf, "pub "), Some(ast::Private) => write!(f.buf, "priv "), Some(ast::Inherited) | None => Ok(()) @@ -473,8 +473,8 @@ impl fmt::Show for VisSpace { } impl fmt::Show for PuritySpace { - fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) -> fmt::Result { - match p.get() { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { ast::UnsafeFn => write!(f.buf, "unsafe "), ast::ExternFn => write!(f.buf, "extern "), ast::ImpureFn => Ok(()) @@ -483,8 +483,8 @@ impl fmt::Show for PuritySpace { } impl fmt::Show for clean::ViewPath { - fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) -> fmt::Result { - match *v { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { clean::SimpleImport(ref name, ref src) => { if *name == src.path.segments.last().unwrap().name { write!(f.buf, "use {};", *src) @@ -510,14 +510,14 @@ impl fmt::Show for clean::ViewPath { } impl fmt::Show for clean::ImportSource { - fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) -> fmt::Result { - match v.did { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.did { // FIXME: shouldn't be restricted to just local imports Some(did) if ast_util::is_local(did) => { - resolved_path(f.buf, did.node, &v.path, true) + resolved_path(f.buf, did.node, &self.path, true) } _ => { - for (i, seg) in v.path.segments.iter().enumerate() { + for (i, seg) in self.path.segments.iter().enumerate() { if i > 0 { if_ok!(write!(f.buf, "::")) } @@ -530,21 +530,21 @@ impl fmt::Show for clean::ImportSource { } impl fmt::Show for clean::ViewListIdent { - fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) -> fmt::Result { - match v.source { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.source { // FIXME: shouldn't be limited to just local imports Some(did) if ast_util::is_local(did) => { let path = clean::Path { global: false, segments: ~[clean::PathSegment { - name: v.name.clone(), + name: self.name.clone(), lifetimes: ~[], types: ~[], }] }; resolved_path(f.buf, did.node, &path, false) } - _ => write!(f.buf, "{}", v.name), + _ => write!(f.buf, "{}", self.name), } } } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index c2203a352c5..63748203a1a 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -211,8 +211,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { } impl<'a> fmt::Show for Markdown<'a> { - fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { - let Markdown(md) = *md; + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let Markdown(md) = *self; // This is actually common enough to special-case if md.len() == 0 { return Ok(()) } render(fmt.buf, md.as_slice()) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index cf80628da77..5bd970834a6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -801,8 +801,8 @@ impl<'a> Item<'a> { } impl<'a> fmt::Show for Item<'a> { - fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { - match attr::find_stability(it.item.attrs.iter()) { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match attr::find_stability(self.item.attrs.iter()) { Some(ref stability) => { if_ok!(write!(fmt.buf, "<a class='stability {lvl}' title='{reason}'>{lvl}</a>", @@ -815,29 +815,29 @@ impl<'a> fmt::Show for Item<'a> { None => {} } - if it.cx.include_sources { + if self.cx.include_sources { let mut path = ~[]; - clean_srcpath(it.item.source.filename.as_bytes(), |component| { + clean_srcpath(self.item.source.filename.as_bytes(), |component| { path.push(component.to_owned()); }); - let href = if it.item.source.loline == it.item.source.hiline { - format!("{}", it.item.source.loline) + let href = if self.item.source.loline == self.item.source.hiline { + format!("{}", self.item.source.loline) } else { - format!("{}-{}", it.item.source.loline, it.item.source.hiline) + format!("{}-{}", self.item.source.loline, self.item.source.hiline) }; if_ok!(write!(fmt.buf, "<a class='source' href='{root}src/{crate}/{path}.html\\#{href}'>\ [src]</a>", - root = it.cx.root_path, - crate = it.cx.layout.crate, + root = self.cx.root_path, + crate = self.cx.layout.crate, path = path.connect("/"), href = href)); } // Write the breadcrumb trail header for the top if_ok!(write!(fmt.buf, "<h1 class='fqn'>")); - match it.item.inner { + match self.item.inner { clean::ModuleItem(..) => if_ok!(write!(fmt.buf, "Module ")), clean::FunctionItem(..) => if_ok!(write!(fmt.buf, "Function ")), clean::TraitItem(..) => if_ok!(write!(fmt.buf, "Trait ")), @@ -845,8 +845,8 @@ impl<'a> fmt::Show for Item<'a> { clean::EnumItem(..) => if_ok!(write!(fmt.buf, "Enum ")), _ => {} } - let cur = it.cx.current.as_slice(); - let amt = if it.ismodule() { cur.len() - 1 } else { cur.len() }; + let cur = self.cx.current.as_slice(); + let amt = if self.ismodule() { cur.len() - 1 } else { cur.len() }; for (i, component) in cur.iter().enumerate().take(amt) { let mut trail = ~""; for _ in range(0, cur.len() - i - 1) { @@ -856,17 +856,17 @@ impl<'a> fmt::Show for Item<'a> { trail, component.as_slice())); } if_ok!(write!(fmt.buf, "<a class='{}' href=''>{}</a></h1>", - shortty(it.item), it.item.name.get_ref().as_slice())); + shortty(self.item), self.item.name.get_ref().as_slice())); - match it.item.inner { - clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx, - it.item, m.items), + match self.item.inner { + clean::ModuleItem(ref m) => item_module(fmt.buf, self.cx, + self.item, m.items), clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => - item_function(fmt.buf, it.item, f), - clean::TraitItem(ref t) => item_trait(fmt.buf, it.item, t), - clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s), - clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e), - clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t), + item_function(fmt.buf, self.item, f), + clean::TraitItem(ref t) => item_trait(fmt.buf, self.item, t), + clean::StructItem(ref s) => item_struct(fmt.buf, self.item, s), + clean::EnumItem(ref e) => item_enum(fmt.buf, self.item, e), + clean::TypedefItem(ref t) => item_typedef(fmt.buf, self.item, t), _ => Ok(()) } } @@ -992,9 +992,8 @@ fn item_module(w: &mut Writer, cx: &Context, clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => { struct Initializer<'a>(&'a str); impl<'a> fmt::Show for Initializer<'a> { - fn fmt(s: &Initializer<'a>, - f: &mut fmt::Formatter) -> fmt::Result { - let Initializer(s) = *s; + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let Initializer(s) = *self; if s.len() == 0 { return Ok(()); } if_ok!(write!(f.buf, "<code> = </code>")); let tag = if s.contains("\n") { "pre" } else { "code" }; @@ -1518,9 +1517,9 @@ fn item_typedef(w: &mut Writer, it: &clean::Item, } impl<'a> fmt::Show for Sidebar<'a> { - fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { - let cx = s.cx; - let it = s.item; + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let cx = self.cx; + let it = self.item; if_ok!(write!(fmt.buf, "<p class='location'>")); let len = cx.current.len() - if it.is_mod() {1} else {0}; for (i, name) in cx.current.iter().take(len).enumerate() { @@ -1588,8 +1587,8 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> { } impl<'a> fmt::Show for Source<'a> { - fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) -> fmt::Result { - let Source(s) = *s; + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let Source(s) = *self; let lines = s.lines().len(); let mut cols = 0; let mut tmp = lines; diff --git a/src/libsemver/lib.rs b/src/libsemver/lib.rs index 9c5dd656d42..7d50cf551a0 100644 --- a/src/libsemver/lib.rs +++ b/src/libsemver/lib.rs @@ -36,6 +36,7 @@ use std::char; use std::cmp; use std::fmt; +use std::fmt::Show; use std::option::{Option, Some, None}; use std::to_str::ToStr; @@ -62,10 +63,10 @@ impl cmp::Ord for Identifier { impl fmt::Show for Identifier { #[inline] - fn fmt(version: &Identifier, f: &mut fmt::Formatter) -> fmt::Result { - match *version { - Numeric(ref n) => fmt::Show::fmt(n, f), - AlphaNumeric(ref s) => fmt::Show::fmt(s, f) + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Numeric(ref n) => n.fmt(f), + AlphaNumeric(ref s) => s.fmt(f) } } } @@ -97,20 +98,20 @@ pub struct Version { impl fmt::Show for Version { #[inline] - fn fmt(version: &Version, f: &mut fmt::Formatter) -> fmt::Result { - if_ok!(write!(f.buf, "{}.{}.{}", version.major, version.minor, version.patch)) - if !version.pre.is_empty() { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(write!(f.buf, "{}.{}.{}", self.major, self.minor, self.patch)) + if !self.pre.is_empty() { if_ok!(write!(f.buf, "-")); - for (i, x) in version.pre.iter().enumerate() { + for (i, x) in self.pre.iter().enumerate() { if i != 0 { if_ok!(write!(f.buf, ".")) }; - if_ok!(fmt::Show::fmt(x, f)); + if_ok!(x.fmt(f)); } } - if !version.build.is_empty() { + if !self.build.is_empty() { if_ok!(write!(f.buf, "+")); - for (i, x) in version.build.iter().enumerate() { + for (i, x) in self.build.iter().enumerate() { if i != 0 { if_ok!(write!(f.buf, ".")) }; - if_ok!(fmt::Show::fmt(x, f)); + if_ok!(x.fmt(f)); } } Ok(()) diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 40ad1fb250a..d2e9fe040f7 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -166,11 +166,11 @@ method of the signature: # mod fmt { pub type Result = (); } # struct T; # trait SomeName<T> { -fn fmt(value: &T, f: &mut std::fmt::Formatter) -> fmt::Result; +fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result; # } ``` -Your type will be passed by-reference in `value`, and then the function should +Your type will be passed as `self` by-reference, and then the function should emit output into the `f.buf` stream. It is up to each format trait implementation to correctly adhere to the requested formatting parameters. The values of these parameters will be listed in the fields of the `Formatter` @@ -195,19 +195,19 @@ struct Vector2D { } impl fmt::Show for Vector2D { - fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // 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 // various flags provided to format strings. - write!(f.buf, "({}, {})", obj.x, obj.y) + write!(f.buf, "({}, {})", self.x, self.y) } } // Different traits allow different forms of output of a type. The meaning of // this format is to print the magnitude of a vector. impl fmt::Binary for Vector2D { - fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result { - let magnitude = (obj.x * obj.x + obj.y * obj.y) as f64; + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let magnitude = (self.x * self.x + self.y * self.y) as f64; let magnitude = magnitude.sqrt(); // Respect the formatting flags by using the helper method @@ -558,50 +558,50 @@ 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 Show { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Show { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `b` character #[allow(missing_doc)] -pub trait Bool { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Bool { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `c` character #[allow(missing_doc)] -pub trait Char { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Char { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `i` and `d` characters #[allow(missing_doc)] -pub trait Signed { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Signed { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `u` character #[allow(missing_doc)] -pub trait Unsigned { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Unsigned { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `o` character #[allow(missing_doc)] -pub trait Octal { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Octal { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `b` character #[allow(missing_doc)] -pub trait Binary { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Binary { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `x` character #[allow(missing_doc)] -pub trait LowerHex { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait LowerHex { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `X` character #[allow(missing_doc)] -pub trait UpperHex { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait UpperHex { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `s` character #[allow(missing_doc)] -pub trait String { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait String { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `?` character #[allow(missing_doc)] -pub trait Poly { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Poly { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `p` character #[allow(missing_doc)] -pub trait Pointer { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Pointer { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `f` character #[allow(missing_doc)] -pub trait Float { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait Float { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `e` character #[allow(missing_doc)] -pub trait LowerExp { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait LowerExp { fn fmt(&self, &mut Formatter) -> Result; } /// Format trait for the `E` character #[allow(missing_doc)] -pub trait UpperExp { fn fmt(&Self, &mut Formatter) -> Result; } +pub trait UpperExp { fn fmt(&self, &mut Formatter) -> Result; } // FIXME #11938 - UFCS would make us able call the above methods // directly Show::show(x, fmt). @@ -615,7 +615,7 @@ macro_rules! uniform_fn_call_workaround { $( #[doc(hidden)] pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result { - $trait_::fmt(x, fmt) + x.fmt(fmt) } )* } @@ -1042,44 +1042,44 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result, /// (such as for select), then it invokes this method. #[doc(hidden)] #[inline] pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> { - argument(String::fmt, s) + argument(secret_string, s) } /// When the compiler determines that the type of an argument *must* be a uint /// (such as for plural), then it invokes this method. #[doc(hidden)] #[inline] pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { - argument(Unsigned::fmt, s) + argument(secret_unsigned, s) } // Implementations of the core formatting traits impl Bool for bool { - fn fmt(b: &bool, f: &mut Formatter) -> Result { - String::fmt(&(if *b {"true"} else {"false"}), f) + fn fmt(&self, f: &mut Formatter) -> Result { + secret_string(&(if *self {"true"} else {"false"}), f) } } impl<'a, T: str::Str> String for T { - fn fmt(s: &T, f: &mut Formatter) -> Result { - f.pad(s.as_slice()) + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad(self.as_slice()) } } impl Char for char { - fn fmt(c: &char, f: &mut Formatter) -> Result { + fn fmt(&self, f: &mut Formatter) -> Result { let mut utf8 = [0u8, ..4]; - let amt = c.encode_utf8(utf8); + let amt = self.encode_utf8(utf8); let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) }; - String::fmt(&s, f) + secret_string(&s, f) } } macro_rules! int_base(($ty:ident, $into:ident, $base:expr, $name:ident, $prefix:expr) => { impl $name for $ty { - fn fmt(c: &$ty, f: &mut Formatter) -> Result { - ::$into::to_str_bytes(*c as $into, $base, |buf| { + fn fmt(&self, f: &mut Formatter) -> Result { + ::$into::to_str_bytes(*self as $into, $base, |buf| { f.pad_integral(buf, $prefix, true) }) } @@ -1087,8 +1087,8 @@ macro_rules! int_base(($ty:ident, $into:ident, $base:expr, }) macro_rules! upper_hex(($ty:ident, $into:ident) => { impl UpperHex for $ty { - fn fmt(c: &$ty, f: &mut Formatter) -> Result { - ::$into::to_str_bytes(*c as $into, 16, |buf| { + fn fmt(&self, f: &mut Formatter) -> Result { + ::$into::to_str_bytes(*self as $into, 16, |buf| { upperhex(buf, f) }) } @@ -1112,9 +1112,9 @@ macro_rules! integer(($signed:ident, $unsigned:ident) => { // Signed is special because it actuall emits the negative sign, // nothing else should do that, however. impl Signed for $signed { - fn fmt(c: &$signed, f: &mut Formatter) -> Result { - ::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| { - f.pad_integral(buf, "", *c >= 0) + fn fmt(&self, f: &mut Formatter) -> Result { + ::$unsigned::to_str_bytes(self.abs() as $unsigned, 10, |buf| { + f.pad_integral(buf, "", *self >= 0) }) } } @@ -1138,35 +1138,35 @@ integer!(i64, u64) macro_rules! floating(($ty:ident) => { impl Float for $ty { - fn fmt(f: &$ty, fmt: &mut Formatter) -> Result { + fn fmt(&self, fmt: &mut Formatter) -> Result { // FIXME: this shouldn't perform an allocation let s = match fmt.precision { - Some(i) => ::$ty::to_str_exact(f.abs(), i), - None => ::$ty::to_str_digits(f.abs(), 6) + Some(i) => ::$ty::to_str_exact(self.abs(), i), + None => ::$ty::to_str_digits(self.abs(), 6) }; - fmt.pad_integral(s.as_bytes(), "", *f >= 0.0) + fmt.pad_integral(s.as_bytes(), "", *self >= 0.0) } } impl LowerExp for $ty { - fn fmt(f: &$ty, fmt: &mut Formatter) -> Result { + fn fmt(&self, fmt: &mut Formatter) -> Result { // FIXME: this shouldn't perform an allocation let s = match fmt.precision { - Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, false), - None => ::$ty::to_str_exp_digits(f.abs(), 6, false) + Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, false), + None => ::$ty::to_str_exp_digits(self.abs(), 6, false) }; - fmt.pad_integral(s.as_bytes(), "", *f >= 0.0) + fmt.pad_integral(s.as_bytes(), "", *self >= 0.0) } } impl UpperExp for $ty { - fn fmt(f: &$ty, fmt: &mut Formatter) -> Result { + fn fmt(&self, fmt: &mut Formatter) -> Result { // FIXME: this shouldn't perform an allocation let s = match fmt.precision { - Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, true), - None => ::$ty::to_str_exp_digits(f.abs(), 6, true) + Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, true), + None => ::$ty::to_str_exp_digits(self.abs(), 6, true) }; - fmt.pad_integral(s.as_bytes(), "", *f >= 0.0) + fmt.pad_integral(s.as_bytes(), "", *self >= 0.0) } } }) @@ -1174,16 +1174,16 @@ floating!(f32) floating!(f64) impl<T> Poly for T { - fn fmt(t: &T, f: &mut Formatter) -> Result { + fn fmt(&self, f: &mut Formatter) -> Result { match (f.width, f.precision) { (None, None) => { - repr::write_repr(f.buf, t) + repr::write_repr(f.buf, self) } // If we have a specified width for formatting, then we have to make // this allocation of a new string _ => { - let s = repr::repr_to_str(t); + let s = repr::repr_to_str(self); f.pad(s) } } @@ -1191,16 +1191,16 @@ impl<T> Poly for T { } impl<T> Pointer for *T { - fn fmt(t: &*T, f: &mut Formatter) -> Result { + fn fmt(&self, f: &mut Formatter) -> Result { f.flags |= 1 << (parse::FlagAlternate as uint); - ::uint::to_str_bytes(*t as uint, 16, |buf| { + ::uint::to_str_bytes(*self as uint, 16, |buf| { f.pad_integral(buf, "0x", true) }) } } impl<T> Pointer for *mut T { - fn fmt(t: &*mut T, f: &mut Formatter) -> Result { - Pointer::fmt(&(*t as *T), f) + fn fmt(&self, f: &mut Formatter) -> Result { + secret_pointer(&(*self as *T), f) } } @@ -1208,33 +1208,33 @@ impl<T> Pointer for *mut T { macro_rules! delegate(($ty:ty to $other:ident) => { impl<'a> Show for $ty { - fn fmt(me: &$ty, f: &mut Formatter) -> Result { - $other::fmt(me, f) + fn fmt(&self, f: &mut Formatter) -> Result { + (concat_idents!(secret_, $other)(self, f)) } } }) -delegate!(int to Signed) -delegate!( i8 to Signed) -delegate!(i16 to Signed) -delegate!(i32 to Signed) -delegate!(i64 to Signed) -delegate!(uint to Unsigned) -delegate!( u8 to Unsigned) -delegate!( u16 to Unsigned) -delegate!( u32 to Unsigned) -delegate!( u64 to Unsigned) -delegate!(~str to String) -delegate!(&'a str to String) -delegate!(bool to Bool) -delegate!(char to Char) -delegate!(f32 to Float) -delegate!(f64 to Float) +delegate!(int to signed) +delegate!( i8 to signed) +delegate!(i16 to signed) +delegate!(i32 to signed) +delegate!(i64 to signed) +delegate!(uint to unsigned) +delegate!( u8 to unsigned) +delegate!( u16 to unsigned) +delegate!( u32 to unsigned) +delegate!( u64 to unsigned) +delegate!(~str to string) +delegate!(&'a str to string) +delegate!(bool to bool) +delegate!(char to char) +delegate!(f32 to float) +delegate!(f64 to float) impl<T> Show for *T { - fn fmt(me: &*T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) } + fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) } } impl<T> Show for *mut T { - fn fmt(me: &*mut T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) } + fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) } } // If you expected tests to be here, look instead at the run-pass/ifmt.rs test, diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 7690c88478f..4d28143c75a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -364,9 +364,9 @@ pub struct IoError { } impl fmt::Show for IoError { - fn fmt(err: &IoError, fmt: &mut fmt::Formatter) -> fmt::Result { - if_ok!(fmt.buf.write_str(err.desc)); - match err.detail { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + if_ok!(fmt.buf.write_str(self.desc)); + match self.detail { Some(ref s) => write!(fmt.buf, " ({})", *s), None => Ok(()) } diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index ccf3d4582de..b515cd9d31c 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -93,8 +93,8 @@ pub enum ProcessExit { impl fmt::Show for ProcessExit { /// Format a ProcessExit enum, to nicely present the information. - fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) -> fmt::Result { - match *obj { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { ExitStatus(code) => write!(f.buf, "exit code: {}", code), ExitSignal(code) => write!(f.buf, "signal: {}", code), } diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 7bb29fdfacf..5d986a73ca1 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -382,8 +382,8 @@ impl<T: Default> Option<T> { impl<T: fmt::Show> fmt::Show for Option<T> { #[inline] - fn fmt(s: &Option<T>, f: &mut fmt::Formatter) -> fmt::Result { - match *s { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { Some(ref t) => write!(f.buf, "Some({})", *t), None => write!(f.buf, "None") } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index fb67f82d612..78cae296457 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -942,8 +942,8 @@ pub enum MapError { } impl fmt::Show for MapError { - fn fmt(val: &MapError, out: &mut fmt::Formatter) -> fmt::Result { - let str = match *val { + fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result { + let str = match *self { ErrFdNotAvail => "fd not available for reading or writing", ErrInvalidFd => "Invalid fd", ErrUnaligned => { diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 3af42db194e..18f28994cba 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -494,8 +494,8 @@ pub struct Display<'a, P> { } impl<'a, P: GenericPath> fmt::Show for Display<'a, P> { - fn fmt(d: &Display<P>, f: &mut fmt::Formatter) -> fmt::Result { - d.with_str(|s| f.pad(s)) + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.with_str(|s| f.pad(s)) } } diff --git a/src/libstd/result.rs b/src/libstd/result.rs index 846bba7533f..39e8b6ad6c1 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -208,8 +208,8 @@ impl<T, E> Result<T, E> { impl<T: fmt::Show, E: fmt::Show> fmt::Show for Result<T, E> { #[inline] - fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) -> fmt::Result { - match *s { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { Ok(ref t) => write!(f.buf, "Ok({})", *t), Err(ref e) => write!(f.buf, "Err({})", *e) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 800eda64d51..848f4ba3871 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -36,7 +36,7 @@ pub struct MacroDef { } pub type ItemDecorator = - fn(&ExtCtxt, Span, @ast::MetaItem, ~[@ast::Item]) -> ~[@ast::Item]; + fn(&mut ExtCtxt, Span, @ast::MetaItem, ~[@ast::Item]) -> ~[@ast::Item]; pub struct BasicMacroExpander { expander: MacroExpanderFn, diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index 567b89d3453..17361240628 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -14,7 +14,7 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -pub fn expand_deriving_clone(cx: &ExtCtxt, +pub fn expand_deriving_clone(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) @@ -42,7 +42,7 @@ pub fn expand_deriving_clone(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -pub fn expand_deriving_deep_clone(cx: &ExtCtxt, +pub fn expand_deriving_deep_clone(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) @@ -74,7 +74,7 @@ pub fn expand_deriving_deep_clone(cx: &ExtCtxt, fn cs_clone( name: &str, - cx: &ExtCtxt, trait_span: Span, + cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let clone_ident = substr.method_ident; let ctor_ident; diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 99b5163214a..a469c4a960b 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -14,17 +14,17 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -pub fn expand_deriving_eq(cx: &ExtCtxt, +pub fn expand_deriving_eq(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different - fn cs_eq(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { + fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { cs_and(|cx, span, _, _| cx.expr_bool(span, false), cx, span, substr) } - fn cs_ne(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { + fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { cs_or(|cx, span, _, _| cx.expr_bool(span, true), cx, span, substr) } diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 5a02d8eead8..83f623e3066 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -15,7 +15,7 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -pub fn expand_deriving_ord(cx: &ExtCtxt, +pub fn expand_deriving_ord(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { @@ -51,7 +51,7 @@ pub fn expand_deriving_ord(cx: &ExtCtxt, } /// Strict inequality. -fn cs_op(less: bool, equal: bool, cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { +fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { let op = if less {ast::BiLt} else {ast::BiGt}; cs_fold( false, // need foldr, diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index 6a1aaeb2f9e..0a38a2ce30d 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -14,11 +14,11 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -pub fn expand_deriving_totaleq(cx: &ExtCtxt, +pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { - fn cs_equals(cx: &ExtCtxt, span: Span, substr: &Substructure) -> @Expr { + fn cs_equals(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { cs_and(|cx, span, _, _| cx.expr_bool(span, false), cx, span, substr) } diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index f1e360f20ba..27a766c0e75 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -16,7 +16,7 @@ use ext::build::AstBuilder; use ext::deriving::generic::*; use std::cmp::{Ordering, Equal, Less, Greater}; -pub fn expand_deriving_totalord(cx: &ExtCtxt, +pub fn expand_deriving_totalord(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { @@ -44,7 +44,7 @@ pub fn expand_deriving_totalord(cx: &ExtCtxt, } -pub fn ordering_const(cx: &ExtCtxt, span: Span, cnst: Ordering) -> ast::Path { +pub fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path { let cnst = match cnst { Less => "Less", Equal => "Equal", @@ -56,7 +56,7 @@ pub fn ordering_const(cx: &ExtCtxt, span: Span, cnst: Ordering) -> ast::Path { cx.ident_of(cnst)]) } -pub fn cs_cmp(cx: &ExtCtxt, span: Span, +pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { let test_id = cx.ident_of("__test"); let equals_path = ordering_const(cx, span, Equal); @@ -106,8 +106,10 @@ pub fn cs_cmp(cx: &ExtCtxt, span: Span, // an earlier nonmatching variant is Less than a // later one. [(self_var, _, _), - (other_var, _, _)] => cx.expr_path(ordering_const(cx, span, - self_var.cmp(&other_var))), + (other_var, _, _)] => { + let order = ordering_const(cx, span, self_var.cmp(&other_var)); + cx.expr_path(order) + } _ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(TotalOrd)`") } }, diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index ad7b3a2e950..7324500a8a0 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -21,7 +21,7 @@ use ext::deriving::generic::*; use parse::token::InternedString; use parse::token; -pub fn expand_deriving_decodable(cx: &ExtCtxt, +pub fn expand_deriving_decodable(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { @@ -53,7 +53,7 @@ pub fn expand_deriving_decodable(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn decodable_substructure(cx: &ExtCtxt, trait_span: Span, +fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let decoder = substr.nonself_args[0]; let recurse = ~[cx.ident_of("serialize"), @@ -77,7 +77,7 @@ fn decodable_substructure(cx: &ExtCtxt, trait_span: Span, trait_span, substr.type_ident, summary, - |span, name, field| { + |cx, span, name, field| { cx.expr_method_call(span, blkdecoder, read_struct_field, ~[cx.expr_str(span, name), cx.expr_uint(span, field), @@ -108,10 +108,10 @@ fn decodable_substructure(cx: &ExtCtxt, trait_span: Span, v_span, name, parts, - |span, _, field| { + |cx, span, _, field| { + let idx = cx.expr_uint(span, field); cx.expr_method_call(span, blkdecoder, rvariant_arg, - ~[cx.expr_uint(span, field), - lambdadecode]) + ~[idx, lambdadecode]) }); arms.push(cx.arm(v_span, @@ -143,11 +143,11 @@ fn decodable_substructure(cx: &ExtCtxt, trait_span: Span, /// Create a decoder for a single enum variant/struct: /// - `outer_pat_ident` is the name of this enum variant/struct /// - `getarg` should retrieve the `uint`-th field with name `@str`. -fn decode_static_fields(cx: &ExtCtxt, +fn decode_static_fields(cx: &mut ExtCtxt, trait_span: Span, outer_pat_ident: Ident, fields: &StaticFields, - getarg: |Span, InternedString, uint| -> @Expr) + getarg: |&mut ExtCtxt, Span, InternedString, uint| -> @Expr) -> @Expr { match *fields { Unnamed(ref fields) => { @@ -155,7 +155,7 @@ fn decode_static_fields(cx: &ExtCtxt, cx.expr_ident(trait_span, outer_pat_ident) } else { let fields = fields.iter().enumerate().map(|(i, &span)| { - getarg(span, + getarg(cx, span, token::intern_and_get_ident(format!("_field{}", i)), i) @@ -167,9 +167,8 @@ fn decode_static_fields(cx: &ExtCtxt, Named(ref fields) => { // use the field's span to get nicer error messages. let fields = fields.iter().enumerate().map(|(i, &(name, span))| { - cx.field_imm(span, - name, - getarg(span, token::get_ident(name.name), i)) + let arg = getarg(cx, span, token::get_ident(name.name), i); + cx.field_imm(span, name, arg) }).collect(); cx.expr_struct_ident(trait_span, outer_pat_ident, fields) } diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index 22f850d5609..922ee164353 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -14,7 +14,7 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -pub fn expand_deriving_default(cx: &ExtCtxt, +pub fn expand_deriving_default(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) @@ -41,7 +41,7 @@ pub fn expand_deriving_default(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn default_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { +fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let default_ident = ~[ cx.ident_of("std"), cx.ident_of("default"), diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index a44e4af5b6b..4de31adc7f2 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -82,7 +82,7 @@ use ext::build::AstBuilder; use ext::deriving::generic::*; use parse::token; -pub fn expand_deriving_encodable(cx: &ExtCtxt, +pub fn expand_deriving_encodable(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { @@ -114,7 +114,7 @@ pub fn expand_deriving_encodable(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn encodable_substructure(cx: &ExtCtxt, trait_span: Span, +fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let encoder = substr.nonself_args[0]; // throw an underscore in front to suppress unused variable warnings diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 992ee3175ed..8c06f0b8c8a 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -194,7 +194,7 @@ mod ty; pub struct TraitDef<'a> { /// The extension context - cx: &'a ExtCtxt<'a>, + cx: &'a mut ExtCtxt<'a>, /// The span for the current #[deriving(Foo)] header. span: Span, @@ -304,7 +304,7 @@ Combine the values of all the fields together. The last argument is all the fields of all the structures, see above for details. */ pub type CombineSubstructureFunc<'a> = - 'a |&ExtCtxt, Span, &Substructure| -> @Expr; + 'a |&mut ExtCtxt, Span, &Substructure| -> @Expr; /** Deal with non-matching enum variants, the arguments are a list @@ -312,7 +312,7 @@ representing each variant: (variant index, ast::Variant instance, [variant fields]), and a list of the nonself args of the type */ pub type EnumNonMatchFunc<'a> = - 'a |&ExtCtxt, + 'a |&mut ExtCtxt, Span, &[(uint, P<ast::Variant>, ~[(Span, Option<Ident>, @Expr)])], &[@Expr]| @@ -356,7 +356,7 @@ impl<'a> TraitDef<'a> { fn create_derived_impl(&self, type_ident: Ident, generics: &Generics, methods: ~[@ast::Method]) -> @ast::Item { - let cx = self.cx; + let cx = &*self.cx; let trait_path = self.path.to_path(cx, self.span, type_ident, generics); let mut trait_generics = self.generics.to_generics(cx, self.span, @@ -764,7 +764,7 @@ impl<'a> MethodDef<'a> { matches_so_far: &mut ~[(uint, P<ast::Variant>, ~[(Span, Option<Ident>, @Expr)])], match_count: uint) -> @Expr { - let cx = trait_.cx; + let cx = &trait_.cx; if match_count == self_args.len() { // we've matched against all arguments, so make the final // expression at the bottom of the match tree @@ -990,7 +990,7 @@ impl<'a> TraitDef<'a> { prefix: &str, mutbl: ast::Mutability) -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) { - let cx = self.cx; + let cx = &self.cx; if struct_def.fields.is_empty() { return ( @@ -1050,7 +1050,7 @@ impl<'a> TraitDef<'a> { prefix: &str, mutbl: ast::Mutability) -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) { - let cx = self.cx; + let cx = &*self.cx; let variant_ident = variant.node.name; match variant.node.kind { ast::TupleVariantKind(ref variant_args) => { @@ -1093,10 +1093,10 @@ Fold the fields. `use_foldl` controls whether this is done left-to-right (`true`) or right-to-left (`false`). */ pub fn cs_fold(use_foldl: bool, - f: |&ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr, + f: |&mut ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr, base: @Expr, enum_nonmatch_f: EnumNonMatchFunc, - cx: &ExtCtxt, + cx: &mut ExtCtxt, trait_span: Span, substructure: &Substructure) -> @Expr { @@ -1132,9 +1132,9 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1), ~~~ */ #[inline] -pub fn cs_same_method(f: |&ExtCtxt, Span, ~[@Expr]| -> @Expr, +pub fn cs_same_method(f: |&mut ExtCtxt, Span, ~[@Expr]| -> @Expr, enum_nonmatch_f: EnumNonMatchFunc, - cx: &ExtCtxt, + cx: &mut ExtCtxt, trait_span: Span, substructure: &Substructure) -> @Expr { @@ -1166,10 +1166,10 @@ fields. `use_foldl` controls whether this is done left-to-right */ #[inline] pub fn cs_same_method_fold(use_foldl: bool, - f: |&ExtCtxt, Span, @Expr, @Expr| -> @Expr, + f: |&mut ExtCtxt, Span, @Expr, @Expr| -> @Expr, base: @Expr, enum_nonmatch_f: EnumNonMatchFunc, - cx: &ExtCtxt, + cx: &mut ExtCtxt, trait_span: Span, substructure: &Substructure) -> @Expr { @@ -1196,7 +1196,7 @@ on all the fields. #[inline] pub fn cs_binop(binop: ast::BinOp, base: @Expr, enum_nonmatch_f: EnumNonMatchFunc, - cx: &ExtCtxt, trait_span: Span, + cx: &mut ExtCtxt, trait_span: Span, substructure: &Substructure) -> @Expr { cs_same_method_fold( true, // foldl is good enough @@ -1214,7 +1214,7 @@ pub fn cs_binop(binop: ast::BinOp, base: @Expr, /// cs_binop with binop == or #[inline] pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc, - cx: &ExtCtxt, span: Span, + cx: &mut ExtCtxt, span: Span, substructure: &Substructure) -> @Expr { cs_binop(ast::BiOr, cx.expr_bool(span, false), enum_nonmatch_f, @@ -1224,7 +1224,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc, /// cs_binop with binop == and #[inline] pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc, - cx: &ExtCtxt, span: Span, + cx: &mut ExtCtxt, span: Span, substructure: &Substructure) -> @Expr { cs_binop(ast::BiAnd, cx.expr_bool(span, true), enum_nonmatch_f, diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index d82e1ef1842..53805694725 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -15,7 +15,7 @@ use ext::build::AstBuilder; use ext::deriving::generic::*; -pub fn expand_deriving_iter_bytes(cx: &ExtCtxt, +pub fn expand_deriving_iter_bytes(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { @@ -45,7 +45,7 @@ pub fn expand_deriving_iter_bytes(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn iter_bytes_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { +fn iter_bytes_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let (lsb0, f)= match substr.nonself_args { [l, f] => (l, f), _ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(IterBytes)`") diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 9c487146639..01e31fc5724 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -18,8 +18,7 @@ library. */ -use ast::{EnumDef, Ident, Item, Generics, StructDef}; -use ast::{MetaItem, MetaList, MetaNameValue, MetaWord}; +use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord}; use ext::base::ExtCtxt; use codemap::Span; @@ -29,6 +28,7 @@ pub mod encodable; pub mod decodable; pub mod rand; pub mod to_str; +pub mod show; pub mod zero; pub mod default; pub mod primitive; @@ -45,20 +45,7 @@ pub mod totalord; pub mod generic; -pub type ExpandDerivingStructDefFn<'a> = 'a |&ExtCtxt, - Span, - x: &StructDef, - Ident, - y: &Generics| - -> @Item; -pub type ExpandDerivingEnumDefFn<'a> = 'a |&ExtCtxt, - Span, - x: &EnumDef, - Ident, - y: &Generics| - -> @Item; - -pub fn expand_meta_deriving(cx: &ExtCtxt, +pub fn expand_meta_deriving(cx: &mut ExtCtxt, _span: Span, mitem: @MetaItem, in_items: ~[@Item]) @@ -97,6 +84,7 @@ pub fn expand_meta_deriving(cx: &ExtCtxt, "Rand" => expand!(rand::expand_deriving_rand), "ToStr" => expand!(to_str::expand_deriving_to_str), + "Show" => expand!(show::expand_deriving_show), "Zero" => expand!(zero::expand_deriving_zero), "Default" => expand!(default::expand_deriving_default), diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index e2f72e87085..86c46705d81 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -16,7 +16,7 @@ use ext::build::AstBuilder; use ext::deriving::generic::*; use parse::token::InternedString; -pub fn expand_deriving_from_primitive(cx: &ExtCtxt, +pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) -> ~[@Item] { @@ -65,7 +65,7 @@ pub fn expand_deriving_from_primitive(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn cs_from(name: &str, cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { +fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let n = match substr.nonself_args { [n] => n, _ => cx.span_bug(trait_span, "Incorrect number of arguments in `deriving(FromPrimitive)`") diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index a22822c2ddc..15595f6eddc 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -16,7 +16,7 @@ use ext::build::{AstBuilder}; use ext::deriving::generic::*; use opt_vec; -pub fn expand_deriving_rand(cx: &ExtCtxt, +pub fn expand_deriving_rand(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) @@ -50,7 +50,7 @@ pub fn expand_deriving_rand(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { +fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let rng = match substr.nonself_args { [rng] => ~[ rng ], _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`") @@ -112,9 +112,8 @@ fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @ let i_expr = cx.expr_uint(v_span, i); let pat = cx.pat_lit(v_span, i_expr); - cx.arm(v_span, - ~[ pat ], - rand_thing(cx, v_span, ident, summary, |sp| rand_call(sp))) + let thing = rand_thing(cx, v_span, ident, summary, |sp| rand_call(sp)); + cx.arm(v_span, ~[ pat ], thing) }).collect::<~[ast::Arm]>(); // _ => {} at the end. Should never occur @@ -128,7 +127,7 @@ fn rand_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @ _ => cx.bug("Non-static method in `deriving(Rand)`") }; - fn rand_thing(cx: &ExtCtxt, + fn rand_thing(cx: &mut ExtCtxt, trait_span: Span, ctor_ident: Ident, summary: &StaticFields, diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs new file mode 100644 index 00000000000..67cfd151f62 --- /dev/null +++ b/src/libsyntax/ext/deriving/show.rs @@ -0,0 +1,138 @@ +// Copyright 2014 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 ast; +use ast::{MetaItem, Item, Expr}; +use codemap::Span; +use ext::format; +use ext::base::ExtCtxt; +use ext::build::AstBuilder; +use ext::deriving::generic::*; + +use parse::token; + +use std::hashmap::HashMap; + +pub fn expand_deriving_show(cx: &mut ExtCtxt, + span: Span, + mitem: @MetaItem, + in_items: ~[@Item]) + -> ~[@Item] { + // &mut ::std::fmt::Formatter + let fmtr = Ptr(~Literal(Path::new(~["std", "fmt", "Formatter"])), + Borrowed(None, ast::MutMutable)); + + let trait_def = TraitDef { + cx: cx, span: span, + + path: Path::new(~["std", "fmt", "Show"]), + additional_bounds: ~[], + generics: LifetimeBounds::empty(), + methods: ~[ + MethodDef { + name: "fmt", + generics: LifetimeBounds::empty(), + explicit_self: borrowed_explicit_self(), + args: ~[fmtr], + ret_ty: Literal(Path::new(~["std", "fmt", "Result"])), + inline: false, + const_nonmatching: false, + combine_substructure: show_substructure + } + ] + }; + trait_def.expand(mitem, in_items) +} + +// we construct a format string and then defer to std::fmt, since that +// knows what's up with formatting at so on. +fn show_substructure(cx: &mut ExtCtxt, span: Span, + substr: &Substructure) -> @Expr { + // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {}, + // <field>: {}, ... }` based on the "shape". + // + // Easy start: they all start with the name. + let name = match *substr.fields { + Struct(_) => substr.type_ident, + EnumMatching(_, v, _) => v.node.name, + + EnumNonMatching(..) | StaticStruct(..) | StaticEnum(..) => { + cx.span_bug(span, "nonsensical .fields in `#[deriving(Show)]`") + } + }; + + let mut format_string = token::get_ident(name.name).get().to_owned(); + // the internal fields we're actually formatting + let mut exprs = ~[]; + + // Getting harder... making the format string: + match *substr.fields { + // unit struct/nullary variant: no work necessary! + Struct([]) | EnumMatching(_, _, []) => {} + + Struct(ref fields) | EnumMatching(_, _, ref fields) => { + if 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_); + } + + 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().name); + format_string.push_str(" "); + format_string.push_str(name.get()); + format_string.push_str(": {}"); + + exprs.push(field.self_); + } + + format_string.push_str(" \\}"); + } + } + _ => unreachable!() + } + + // AST construction! + // we're basically calling + // + // format_arg!(|__args| ::std::fmt::write(fmt.buf, __args), "<format_string>", exprs...) + // + // but doing it directly via ext::format. + let formatter = substr.nonself_args[0]; + let buf = cx.expr_field_access(span, formatter, cx.ident_of("buf")); + + let std_write = ~[cx.ident_of("std"), cx.ident_of("fmt"), cx.ident_of("write")]; + let args = cx.ident_of("__args"); + let write_call = cx.expr_call_global(span, std_write, ~[buf, cx.expr_ident(span, args)]); + let format_closure = cx.lambda_expr(span, ~[args], write_call); + + let s = token::intern_and_get_ident(format_string); + let format_string = cx.expr_str(span, s); + + // phew, not our responsibility any more! + format::expand_preparsed_format_args(cx, span, + format_closure, + format_string, exprs, HashMap::new()) +} diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs index 6101d647ca5..2f50d5ad121 100644 --- a/src/libsyntax/ext/deriving/to_str.rs +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -17,7 +17,7 @@ use ext::deriving::generic::*; use parse::token::InternedString; use parse::token; -pub fn expand_deriving_to_str(cx: &ExtCtxt, +pub fn expand_deriving_to_str(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) @@ -49,7 +49,7 @@ pub fn expand_deriving_to_str(cx: &ExtCtxt, // doesn't invoke the to_str() method on each field. Hence we mirror // the logic of the repr_to_str() method, but with tweaks to call to_str() // on sub-fields. -fn to_str_substructure(cx: &ExtCtxt, span: Span, substr: &Substructure) +fn to_str_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr { let to_str = cx.ident_of("to_str"); diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index dd99e821620..ecd06b3f49e 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -14,7 +14,7 @@ use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -pub fn expand_deriving_zero(cx: &ExtCtxt, +pub fn expand_deriving_zero(cx: &mut ExtCtxt, span: Span, mitem: @MetaItem, in_items: ~[@Item]) @@ -57,7 +57,7 @@ pub fn expand_deriving_zero(cx: &ExtCtxt, trait_def.expand(mitem, in_items) } -fn zero_substructure(cx: &ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { +fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> @Expr { let zero_ident = ~[ cx.ident_of("std"), cx.ident_of("num"), diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 9d2a891bf6b..4bc3b804c7f 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -56,78 +56,83 @@ struct Context<'a> { next_arg: uint, } -impl<'a> Context<'a> { - /// Parses the arguments from the given list of tokens, returning None if - /// there's a parse error so we can continue parsing other format! expressions. - fn parse_args(&mut self, sp: Span, tts: &[ast::TokenTree]) - -> (@ast::Expr, Option<@ast::Expr>) { - let mut p = rsparse::new_parser_from_tts(self.ecx.parse_sess(), - self.ecx.cfg(), - tts.to_owned()); - // Parse the leading function expression (maybe a block, maybe a path) - let extra = p.parse_expr(); - if !p.eat(&token::COMMA) { - self.ecx.span_err(sp, "expected token: `,`"); - return (extra, None); - } +/// Parses the arguments from the given list of tokens, returning None +/// if there's a parse error so we can continue parsing other format! +/// expressions. +/// +/// If parsing succeeds, the second return value is: +/// +/// Some((fmtstr, unnamed arguments, named arguments)) +fn parse_args(ecx: &mut ExtCtxt, sp: Span, + tts: &[ast::TokenTree]) -> (@ast::Expr, Option<(@ast::Expr, ~[@ast::Expr], + HashMap<~str, @ast::Expr>)>) { + let mut args = ~[]; + let mut names = HashMap::<~str, @ast::Expr>::new(); - if p.token == token::EOF { - self.ecx.span_err(sp, "requires at least a format string argument"); - return (extra, None); - } - let fmtstr = p.parse_expr(); - let mut named = false; - while p.token != token::EOF { - if !p.eat(&token::COMMA) { - self.ecx.span_err(sp, "expected token: `,`"); - return (extra, None); - } - if p.token == token::EOF { break } // accept trailing commas - if named || (token::is_ident(&p.token) && - p.look_ahead(1, |t| *t == token::EQ)) { - named = true; - let ident = match p.token { - token::IDENT(i, _) => { - p.bump(); - i - } - _ if named => { - self.ecx.span_err(p.span, - "expected ident, positional arguments \ - cannot follow named arguments"); - return (extra, None); - } - _ => { - self.ecx.span_err(p.span, - format!("expected ident for named \ - argument, but found `{}`", - p.this_token_to_str())); - return (extra, None); - } - }; - let interned_name = token::get_ident(ident.name); - let name = interned_name.get(); - p.expect(&token::EQ); - let e = p.parse_expr(); - match self.names.find_equiv(&name) { - None => {} - Some(prev) => { - self.ecx.span_err(e.span, format!("duplicate argument \ - named `{}`", name)); - self.ecx.parse_sess.span_diagnostic.span_note( - prev.span, "previously here"); - continue - } - } - self.names.insert(name.to_str(), e); - } else { - self.args.push(p.parse_expr()); - self.arg_types.push(None); - } - } - return (extra, Some(fmtstr)); + let mut p = rsparse::new_parser_from_tts(ecx.parse_sess(), + ecx.cfg(), + tts.to_owned()); + // Parse the leading function expression (maybe a block, maybe a path) + let extra = p.parse_expr(); + if !p.eat(&token::COMMA) { + ecx.span_err(sp, "expected token: `,`"); + return (extra, None); } + if p.token == token::EOF { + ecx.span_err(sp, "requires at least a format string argument"); + return (extra, None); + } + let fmtstr = p.parse_expr(); + let mut named = false; + while p.token != token::EOF { + if !p.eat(&token::COMMA) { + ecx.span_err(sp, "expected token: `,`"); + return (extra, None); + } + if p.token == token::EOF { break } // accept trailing commas + if named || (token::is_ident(&p.token) && + p.look_ahead(1, |t| *t == token::EQ)) { + named = true; + let ident = match p.token { + token::IDENT(i, _) => { + p.bump(); + i + } + _ if named => { + ecx.span_err(p.span, + "expected ident, positional arguments \ + cannot follow named arguments"); + return (extra, None); + } + _ => { + ecx.span_err(p.span, + format!("expected ident for named argument, but found `{}`", + p.this_token_to_str())); + return (extra, None); + } + }; + let interned_name = token::get_ident(ident.name); + let name = interned_name.get(); + p.expect(&token::EQ); + let e = p.parse_expr(); + match names.find_equiv(&name) { + None => {} + Some(prev) => { + ecx.span_err(e.span, format!("duplicate argument named `{}`", name)); + ecx.parse_sess.span_diagnostic.span_note(prev.span, "previously here"); + continue + } + } + names.insert(name.to_str(), e); + } else { + args.push(p.parse_expr()); + } + } + return (extra, Some((fmtstr, args, names))); +} + +impl<'a> Context<'a> { /// Verifies one piece of a parse string. All errors are not emitted as /// fatal so we can continue giving errors about this and possibly other /// format strings. @@ -758,11 +763,28 @@ impl<'a> Context<'a> { pub fn expand_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult { + + match parse_args(ecx, sp, tts) { + (extra, Some((efmt, args, names))) => { + MRExpr(expand_preparsed_format_args(ecx, sp, extra, efmt, args, names)) + } + (_, None) => MRExpr(ecx.expr_uint(sp, 2)) + } +} + +/// Take the various parts of `format_args!(extra, efmt, args..., +/// name=names...)` and construct the appropriate formatting +/// expression. +pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, + extra: @ast::Expr, + efmt: @ast::Expr, args: ~[@ast::Expr], + names: HashMap<~str, @ast::Expr>) -> @ast::Expr { + let arg_types = vec::from_fn(args.len(), |_| None); let mut cx = Context { ecx: ecx, - args: ~[], - arg_types: ~[], - names: HashMap::new(), + args: args, + arg_types: arg_types, + names: names, name_positions: HashMap::new(), name_types: HashMap::new(), nest_level: 0, @@ -771,10 +793,6 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span, method_statics: ~[], fmtsp: sp, }; - let (extra, efmt) = match cx.parse_args(sp, tts) { - (extra, Some(e)) => (extra, e), - (_, None) => { return MRExpr(cx.ecx.expr_uint(sp, 2)); } - }; cx.fmtsp = efmt.span; // Be sure to recursively expand macros just in case the format string uses // a macro to build the format expression. @@ -783,7 +801,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span, expr, "format argument must be a string literal.") { Some((fmt, _)) => fmt, - None => return MacResult::dummy_expr() + None => return efmt }; let mut parser = parse::Parser::new(fmt.get()); @@ -801,7 +819,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span, match parser.errors.shift() { Some(error) => { cx.ecx.span_err(efmt.span, "invalid format string: " + error); - return MRExpr(efmt); + return efmt; } None => {} } @@ -818,5 +836,5 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span, } } - MRExpr(cx.to_expr(extra)) + cx.to_expr(extra) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 090774ec76f..d32411b4f05 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -588,8 +588,8 @@ impl BytesContainer for InternedString { } impl fmt::Show for InternedString { - fn fmt(obj: &InternedString, f: &mut fmt::Formatter) -> fmt::Result { - write!(f.buf, "{}", obj.string.as_slice()) + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f.buf, "{}", self.string.as_slice()) } } diff --git a/src/test/compile-fail/deriving-span-Show-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Show-enum-struct-variant.rs new file mode 100644 index 00000000000..582c95b746b --- /dev/null +++ b/src/test/compile-fail/deriving-span-Show-enum-struct-variant.rs @@ -0,0 +1,26 @@ +// Copyright 2014 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. + +// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' + +#[feature(struct_variant)]; +extern mod extra; + + +struct Error; + +#[deriving(Show)] +enum Enum { + A { + x: Error //~ ERROR + } +} + +fn main() {} diff --git a/src/test/compile-fail/deriving-span-Show-enum.rs b/src/test/compile-fail/deriving-span-Show-enum.rs new file mode 100644 index 00000000000..92efe01fa38 --- /dev/null +++ b/src/test/compile-fail/deriving-span-Show-enum.rs @@ -0,0 +1,26 @@ +// Copyright 2014 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. + +// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' + +#[feature(struct_variant)]; +extern mod extra; + + +struct Error; + +#[deriving(Show)] +enum Enum { + A( + Error //~ ERROR + ) +} + +fn main() {} diff --git a/src/test/compile-fail/deriving-span-Show-struct.rs b/src/test/compile-fail/deriving-span-Show-struct.rs new file mode 100644 index 00000000000..7eff82f9d13 --- /dev/null +++ b/src/test/compile-fail/deriving-span-Show-struct.rs @@ -0,0 +1,24 @@ +// Copyright 2014 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. + +// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' + +#[feature(struct_variant)]; +extern mod extra; + + +struct Error; + +#[deriving(Show)] +struct Struct { + x: Error //~ ERROR +} + +fn main() {} diff --git a/src/test/compile-fail/deriving-span-Show-tuple-struct.rs b/src/test/compile-fail/deriving-span-Show-tuple-struct.rs new file mode 100644 index 00000000000..600a0400350 --- /dev/null +++ b/src/test/compile-fail/deriving-span-Show-tuple-struct.rs @@ -0,0 +1,24 @@ +// Copyright 2014 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. + +// This file was auto-generated using 'src/etc/generate-keyword-span-tests.py' + +#[feature(struct_variant)]; +extern mod extra; + + +struct Error; + +#[deriving(Show)] +struct Struct( + Error //~ ERROR +); + +fn main() {} diff --git a/src/test/run-pass/deriving-show.rs b/src/test/run-pass/deriving-show.rs new file mode 100644 index 00000000000..40965615506 --- /dev/null +++ b/src/test/run-pass/deriving-show.rs @@ -0,0 +1,42 @@ +// Copyright 2014 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. + +#[feature(struct_variant, macro_rules)]; + +#[deriving(Show)] +struct Unit; + +#[deriving(Show)] +struct Tuple(int, uint); + +#[deriving(Show)] +struct Struct { x: int, y: uint } + +#[deriving(Show)] +enum Enum { + Nullary, + Variant(int, uint), + StructVariant { x: int, y : uint } +} + +macro_rules! t { + ($x:expr, $expected:expr) => { + assert_eq!(format!("{}", $x), $expected.to_owned()) + } +} + +pub fn main() { + t!(Unit, "Unit"); + t!(Tuple(1, 2), "Tuple(1, 2)"); + t!(Struct { x: 1, y: 2 }, "Struct { x: 1, y: 2 }"); + t!(Nullary, "Nullary"); + t!(Variant(1, 2), "Variant(1, 2)"); + t!(StructVariant { x: 1, y: 2 }, "StructVariant { x: 1, y: 2 }"); +} diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index b66446b0cfe..4a82007f060 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -23,12 +23,12 @@ struct A; struct B; impl fmt::Signed for A { - fn fmt(_: &A, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.buf.write("aloha".as_bytes()) } } impl fmt::Signed for B { - fn fmt(_: &B, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.buf.write("adios".as_bytes()) } } diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs index dccdc8ae3ba..8c6a366220c 100644 --- a/src/test/run-pass/logging-only-prints-once.rs +++ b/src/test/run-pass/logging-only-prints-once.rs @@ -17,8 +17,8 @@ use std::fmt; struct Foo(Cell<int>); impl fmt::Show for Foo { - fn fmt(f: &Foo, _fmt: &mut fmt::Formatter) -> fmt::Result { - let Foo(ref f) = *f; + fn fmt(&self, _fmt: &mut fmt::Formatter) -> fmt::Result { + let Foo(ref f) = *self; assert!(f.get() == 0); f.set(1); Ok(())