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("&lt;".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{ -&gt; {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(())