about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-07-11 15:00:40 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-07-17 15:46:43 -0700
commitdb020ab63cd51dd4a25cba2d00117f016128762b (patch)
tree2b6f1e99ba4356f3e3bf5338332c278d2a85109b /src
parentb5729bd60095fb5ca884936775e031cf19900760 (diff)
downloadrust-db020ab63cd51dd4a25cba2d00117f016128762b.tar.gz
rust-db020ab63cd51dd4a25cba2d00117f016128762b.zip
rustc: Implement and enforce instance coherence
Diffstat (limited to 'src')
-rw-r--r--src/cargo/cargo.rs4
-rw-r--r--src/libcore/core.rs14
-rw-r--r--src/libcore/int-template.rs2
-rw-r--r--src/libcore/iter-trait.rs3
-rw-r--r--src/libcore/iter.rs10
-rw-r--r--src/libcore/option.rs1
-rw-r--r--src/libcore/pipes.rs6
-rw-r--r--src/libcore/ptr.rs1
-rw-r--r--src/libcore/str.rs4
-rw-r--r--src/libcore/uint-template.rs1
-rw-r--r--src/libcore/vec.rs30
-rw-r--r--src/libstd/arena.rs9
-rw-r--r--src/libstd/ebml.rs33
-rw-r--r--src/libstd/json.rs11
-rw-r--r--src/libstd/map.rs16
-rw-r--r--src/libstd/net_ip.rs7
-rw-r--r--src/libstd/net_tcp.rs1
-rw-r--r--src/libstd/serialization.rs12
-rw-r--r--src/libstd/smallintmap.rs9
-rw-r--r--src/libstd/time.rs14
-rw-r--r--src/libsyntax/ast_util.rs8
-rw-r--r--src/libsyntax/ext/auto_serialize.rs29
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs52
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs7
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs39
-rw-r--r--src/libsyntax/ext/tt/earley_parser.rs1
-rw-r--r--src/libsyntax/parse/attr.rs16
-rw-r--r--src/libsyntax/parse/common.rs39
-rw-r--r--src/libsyntax/parse/parser.rs17
-rw-r--r--src/libsyntax/parse/token.rs7
-rw-r--r--src/libsyntax/print/pp.rs38
-rw-r--r--src/rustc/driver/driver.rs43
-rw-r--r--src/rustc/driver/session.rs6
-rw-r--r--src/rustc/metadata/csearch.rs9
-rw-r--r--src/rustc/metadata/decoder.rs19
-rw-r--r--src/rustc/middle/astencode.rs93
-rw-r--r--src/rustc/middle/borrowck.rs35
-rw-r--r--src/rustc/middle/borrowck/loan.rs8
-rw-r--r--src/rustc/middle/lint.rs30
-rw-r--r--src/rustc/middle/region.rs22
-rw-r--r--src/rustc/middle/resolve3.rs219
-rw-r--r--src/rustc/middle/trans/base.rs10
-rw-r--r--src/rustc/middle/trans/common.rs10
-rw-r--r--src/rustc/middle/ty.rs10
-rw-r--r--src/rustc/middle/typeck.rs37
-rw-r--r--src/rustc/middle/typeck/check.rs65
-rw-r--r--src/rustc/middle/typeck/check/method.rs188
-rw-r--r--src/rustc/middle/typeck/coherence.rs467
-rw-r--r--src/rustc/middle/typeck/infer.rs31
-rw-r--r--src/rustdoc/attr_pass.rs7
-rw-r--r--src/rustdoc/desc_to_brief_pass.rs2
-rw-r--r--src/rustdoc/doc.rs36
-rw-r--r--src/rustdoc/extract.rs9
-rw-r--r--src/rustdoc/fold.rs24
-rw-r--r--src/rustdoc/markdown_index_pass.rs8
-rw-r--r--src/rustdoc/markdown_pass.rs12
-rw-r--r--src/rustdoc/markdown_writer.rs11
-rw-r--r--src/rustdoc/page_pass.rs11
-rw-r--r--src/rustdoc/path_pass.rs7
-rw-r--r--src/rustdoc/prune_hidden_pass.rs7
-rw-r--r--src/rustdoc/prune_unexported_pass.rs7
-rw-r--r--src/rustdoc/reexport_pass.rs15
-rwxr-xr-xsrc/rustdoc/rustdoc.rs17
-rw-r--r--src/rustdoc/sectionalize_pass.rs2
-rw-r--r--src/rustdoc/sort_item_name_pass.rs1
-rw-r--r--src/rustdoc/sort_item_type_pass.rs2
-rw-r--r--src/rustdoc/sort_pass.rs7
-rw-r--r--src/rustdoc/text_pass.rs2
-rw-r--r--src/rustdoc/trim_pass.rs2
-rw-r--r--src/rustdoc/tystr_pass.rs1
-rw-r--r--src/test/auxiliary/ambig_impl_2_lib.rs5
-rw-r--r--src/test/auxiliary/cci_impl_lib.rs8
-rw-r--r--src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs16
-rw-r--r--src/test/auxiliary/issue-2414-a.rs10
-rw-r--r--src/test/bench/graph500-bfs.rs1
-rw-r--r--src/test/bench/shootout-mandelbrot.rs7
-rw-r--r--src/test/compile-fail/ambig_impl_1.rs3
-rw-r--r--src/test/compile-fail/ambig_impl_2_exe.rs6
-rw-r--r--src/test/compile-fail/ambig_impl_unify.rs10
-rw-r--r--src/test/compile-fail/bad-method-typaram-kind.rs6
-rw-r--r--src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs7
-rw-r--r--src/test/compile-fail/borrowck-loan-rcvr.rs8
-rw-r--r--src/test/compile-fail/iface-test-2.rs2
-rw-r--r--src/test/compile-fail/issue-2063.rs6
-rw-r--r--src/test/compile-fail/issue-2149.rs8
-rw-r--r--src/test/compile-fail/issue-2590.rs6
-rw-r--r--src/test/compile-fail/placement-new-bad-method-type.rs6
-rw-r--r--src/test/compile-fail/pure-modifies-aliased.rs8
-rw-r--r--src/test/compile-fail/pure-overloaded-op.rs9
-rw-r--r--src/test/compile-fail/regions-infer-paramd-indirect.rs9
-rw-r--r--src/test/compile-fail/regions-infer-paramd-method.rs14
-rw-r--r--src/test/run-pass/autoderef-method-newtype.rs6
-rw-r--r--src/test/run-pass/autoderef-method-priority.rs8
-rw-r--r--src/test/run-pass/autoderef-method-twice-but-not-thrice.rs6
-rw-r--r--src/test/run-pass/autoderef-method-twice.rs6
-rw-r--r--src/test/run-pass/autoderef-method.rs6
-rw-r--r--src/test/run-pass/borrowck-newtype-issue-2573.rs8
-rw-r--r--src/test/run-pass/cci_impl_exe.rs1
-rw-r--r--src/test/run-pass/crate-method-reexport-grrrrrrr.rs2
-rw-r--r--src/test/run-pass/fixed_length_vec_glue.rs4
-rw-r--r--src/test/run-pass/impl-variance.rs8
-rw-r--r--src/test/run-pass/int-conversion-coherence.rs16
-rw-r--r--src/test/run-pass/method-attributes.rs2
-rw-r--r--src/test/run-pass/module-polymorphism4-files/trait.rs6
-rw-r--r--src/test/run-pass/monad.rs12
-rw-r--r--src/test/run-pass/operator-overloading-leaks.rs25
-rw-r--r--src/test/run-pass/operator-overloading.rs9
-rw-r--r--src/test/run-pass/rcvr-borrowed-to-region.rs8
-rw-r--r--src/test/run-pass/rcvr-borrowed-to-slice.rs8
-rw-r--r--src/test/run-pass/regions-self-impls.rs6
-rw-r--r--src/test/run-pass/static-impl.rs25
111 files changed, 1740 insertions, 520 deletions
diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs
index 0ac7cf00874..443d4dda020 100644
--- a/src/cargo/cargo.rs
+++ b/src/cargo/cargo.rs
@@ -11,7 +11,7 @@ import result::{ok, err};
 import io::writer_util;
 import std::{map, json, tempfile, term, sort, getopts};
 import map::hashmap;
-import json::to_str;
+import to_str::to_str;
 import getopts::{optflag, optopt, opt_present};
 
 type package = {
@@ -535,7 +535,7 @@ fn load_one_source_package(src: source, p: map::hashmap<~str, json::json>) {
         versions: ~[]
     };
 
-    alt src.packages.position(|pkg| pkg.uuid == uuid ) {
+    alt vec::position(src.packages, |pkg| pkg.uuid == uuid) {
       some(idx) {
         src.packages[idx] = newpkg;
         log(debug, ~"  updated package: " + src.name + ~"/" + name);
diff --git a/src/libcore/core.rs b/src/libcore/core.rs
index c70be013fb7..07dac5270b0 100644
--- a/src/libcore/core.rs
+++ b/src/libcore/core.rs
@@ -5,12 +5,15 @@
 import option::{some, none};
 import option = option::option;
 import path = path::path;
-import str::extensions;
 import tuple::extensions;
+import str::{extensions, str_slice, unique_str};
 import vec::extensions;
+import vec::{const_vector, copyable_vector, immutable_vector};
+import vec::{immutable_copyable_vector, iter_trait_extensions, vec_concat};
+import iter::{base_iter, extended_iter, copyable_iter, times};
 import option::extensions;
 import option_iter::extensions;
-import ptr::extensions;
+import ptr::{extensions, ptr};
 import rand::extensions;
 import result::extensions;
 import int::{num, times};
@@ -26,11 +29,18 @@ import u64::{num, times};
 import float::num;
 import f32::num;
 import f64::num;
+import num::num;
 
 export path, option, some, none, unreachable;
 export extensions;
 // The following exports are the extension impls for numeric types
 export num, times;
+// The following exports are the common traits
+export str_slice, unique_str;
+export const_vector, copyable_vector, immutable_vector;
+export immutable_copyable_vector, iter_trait_extensions, vec_concat;
+export base_iter, copyable_iter, extended_iter;
+export ptr;
 
 // Export the log levels as global constants. Higher levels mean
 // more-verbosity. Error is the bottom level, default logging level is
diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs
index 983d1b9968f..d9fb3dae846 100644
--- a/src/libcore/int-template.rs
+++ b/src/libcore/int-template.rs
@@ -233,6 +233,7 @@ fn test_ifaces() {
 
 #[test]
 fn test_times() {
+    import iter::times;
     let ten = 10 as T;
     let mut accum = 0;
     for ten.times { accum += 1; }
@@ -243,5 +244,6 @@ fn test_times() {
 #[should_fail]
 #[ignore(cfg(windows))]
 fn test_times_negative() {
+    import iter::times;
     for (-10).times { log(error, ~"nope!"); }
 }
diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs
index 80b81753af8..e31824d066d 100644
--- a/src/libcore/iter-trait.rs
+++ b/src/libcore/iter-trait.rs
@@ -8,6 +8,9 @@ export extensions;
 impl extensions<A> of iter::base_iter<A> for IMPL_T<A> {
     fn each(blk: fn(A) -> bool) { EACH(self, blk) }
     fn size_hint() -> option<uint> { SIZE_HINT(self) }
+}
+
+impl extensions<A> of iter::extended_iter<A> for IMPL_T<A> {
     fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
     fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
     fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index e2a321cde23..2e0c778cd5a 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -3,6 +3,16 @@ iface base_iter<A> {
     fn size_hint() -> option<uint>;
 }
 
+trait extended_iter<A> {
+    fn eachi(blk: fn(uint, A) -> bool);
+    fn all(blk: fn(A) -> bool) -> bool;
+    fn any(blk: fn(A) -> bool) -> bool;
+    fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B;
+    fn contains(x: A) -> bool;
+    fn count(x: A) -> uint;
+    fn position(f: fn(A) -> bool) -> option<uint>;
+}
+
 iface times {
     fn times(it: fn() -> bool);
 }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index dabfa04ef24..2b9794987ee 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -92,6 +92,7 @@ pure fn iter<T>(opt: option<T>, f: fn(T)) {
     alt opt { none { } some(t) { f(t); } }
 }
 
+#[inline(always)]
 pure fn unwrap<T>(-opt: option<T>) -> T {
     /*!
      * Moves a value out of an option type and returns it.
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index 13a90ac7ae5..33f5fe958a5 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -578,7 +578,11 @@ impl<T: send> of selectable for pipes::port<T> {
 
 type shared_chan<T: send> = arc::exclusive<pipes::chan<T>>;
 
-impl chan<T: send> for shared_chan<T> {
+trait send_on_shared_chan<T> {
+    fn send(+x: T);
+}
+
+impl chan<T: send> of send_on_shared_chan<T> for shared_chan<T> {
     fn send(+x: T) {
         let mut xx = some(x);
         do self.with |_c, chan| {
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 178a68a1c65..ba98fb3c119 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -14,6 +14,7 @@ export memset;
 export buf_len;
 export position;
 export extensions;
+export ptr;
 
 import libc::{c_void, size_t};
 
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index cc5ae30268d..7e83e7aa0ee 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -106,7 +106,9 @@ export
    escape_unicode,
 
    unsafe,
-   extensions;
+   extensions,
+   str_slice,
+   unique_str;
 
 #[abi = "cdecl"]
 extern mod rustrt {
diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs
index 7c4244efd9b..4f35f1a8756 100644
--- a/src/libcore/uint-template.rs
+++ b/src/libcore/uint-template.rs
@@ -278,6 +278,7 @@ fn to_str_radix17() {
 
 #[test]
 fn test_times() {
+    import iter::times;
     let ten = 10 as T;
     let mut accum = 0;
     for ten.times { accum += 1; }
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 60e3373fdbe..1dd4ef5ae43 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -85,6 +85,12 @@ export unpack_const_slice;
 export unsafe;
 export u8;
 export extensions;
+export const_vector;
+export copyable_vector;
+export immutable_vector;
+export immutable_copyable_vector;
+export iter_trait_extensions;
+export vec_concat;
 
 #[abi = "cdecl"]
 extern mod rustrt {
@@ -179,11 +185,12 @@ pure fn len<T>(&&v: &[const T]) -> uint {
  * Creates an immutable vector of size `n_elts` and initializes the elements
  * to the value returned by the function `op`.
  */
-pure fn from_fn<T>(n_elts: uint, op: init_op<T>) -> ~[T] {
+pure fn from_fn<T: copy>(n_elts: uint, op: init_op<T>) -> ~[T] {
     let mut v = ~[];
     unchecked{reserve(v, n_elts);}
     let mut i: uint = 0u;
-    while i < n_elts unsafe { push(v, op(i)); i += 1u; }
+    while i < n_elts unsafe { ref_set(v, i, op(i)); i += 1u; }
+    unsafe { unsafe::set_len(v, n_elts); }
     ret v;
 }
 
@@ -197,8 +204,9 @@ pure fn from_elem<T: copy>(n_elts: uint, t: T) -> ~[T] {
     let mut v = ~[];
     unchecked{reserve(v, n_elts)}
     let mut i: uint = 0u;
-    unsafe { // because push is impure
-        while i < n_elts { push(v, t); i += 1u; }
+    unsafe { // because ref_set is unsafe
+        while i < n_elts { ref_set(v, i, t); i += 1u; }
+        unsafe { unsafe::set_len(v, n_elts); }
     }
     ret v;
 }
@@ -469,6 +477,16 @@ unsafe fn ref<T: copy>(v: &[const T], i: uint) -> T {
 }
 
 #[inline(always)]
+unsafe fn ref_set<T: copy>(v: &[mut T], i: uint, +val: T) {
+    let mut box = some(val);
+    do unpack_mut_slice(v) |p, _len| {
+        let mut box2 = none;
+        box2 <-> box;
+        rusti::move_val_init(*ptr::mut_offset(p, i), option::unwrap(box2));
+    }
+}
+
+#[inline(always)]
 fn push_all<T: copy>(&v: ~[const T], rhs: &[const T]) {
     reserve(v, v.len() + rhs.len());
 
@@ -1591,6 +1609,9 @@ mod u8 {
 impl extensions/&<A> of iter::base_iter<A> for &[const A] {
     fn each(blk: fn(A) -> bool) { each(self, blk) }
     fn size_hint() -> option<uint> { some(len(self)) }
+}
+
+impl extensions/&<A> of iter::extended_iter<A> for &[const A] {
     fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
     fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
     fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
@@ -1599,6 +1620,7 @@ impl extensions/&<A> of iter::base_iter<A> for &[const A] {
     }
     fn contains(x: A) -> bool { iter::contains(self, x) }
     fn count(x: A) -> uint { iter::count(self, x) }
+    fn position(f: fn(A) -> bool) -> option<uint> { iter::position(self, f) }
 }
 
 trait iter_trait_extensions<A> {
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 65fcd0a59ca..2df720e6fe1 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -6,7 +6,12 @@ import list;
 import list::{list, cons, nil};
 
 type chunk = {data: ~[u8], mut fill: uint};
-type arena = {mut chunks: @list<@chunk>};
+
+type arena_ = {mut chunks: @list<@chunk>};
+
+enum arena {
+    arena_(arena_)
+}
 
 fn chunk(size: uint) -> @chunk {
     let mut v = ~[];
@@ -15,7 +20,7 @@ fn chunk(size: uint) -> @chunk {
 }
 
 fn arena_with_size(initial_size: uint) -> arena {
-    ret {mut chunks: @cons(chunk(initial_size), @nil)};
+    ret arena_({mut chunks: @cons(chunk(initial_size), @nil)});
 }
 
 fn arena() -> arena {
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index 5f833a20e32..07f578901fd 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -155,7 +155,11 @@ fn doc_as_i32(d: doc) -> i32 { doc_as_u32(d) as i32 }
 fn doc_as_i64(d: doc) -> i64 { doc_as_u64(d) as i64 }
 
 // ebml writing
-type writer = {writer: io::writer, mut size_positions: ~[uint]};
+type writer_ = {writer: io::writer, mut size_positions: ~[uint]};
+
+enum writer {
+    writer_(writer_)
+}
 
 fn write_sized_vuint(w: io::writer, n: uint, size: uint) {
     alt size {
@@ -187,7 +191,7 @@ fn write_vuint(w: io::writer, n: uint) {
 
 fn writer(w: io::writer) -> writer {
     let size_positions: ~[uint] = ~[];
-    ret {writer: w, mut size_positions: size_positions};
+    ret writer_({writer: w, mut size_positions: size_positions});
 }
 
 // FIXME (#2741): Provide a function to write the standard ebml header.
@@ -311,9 +315,12 @@ enum ebml_serializer_tag {
     es_label // Used only when debugging
 }
 
-impl serializer of serialization::serializer for ebml::writer {
-    fn emit_nil() {}
+trait serializer_priv {
+    fn _emit_tagged_uint(t: ebml_serializer_tag, v: uint);
+    fn _emit_label(label: ~str);
+}
 
+impl serializer of serializer_priv for ebml::writer {
     // used internally to emit things like the vector length and so on
     fn _emit_tagged_uint(t: ebml_serializer_tag, v: uint) {
         assert v <= 0xFFFF_FFFF_u;
@@ -329,6 +336,10 @@ impl serializer of serialization::serializer for ebml::writer {
         // try and check failures more quickly.
         if debug { self.wr_tagged_str(es_label as uint, label) }
     }
+}
+
+impl serializer of serialization::serializer for ebml::writer {
+    fn emit_nil() {}
 
     fn emit_uint(v: uint) { self.wr_tagged_u64(es_uint as uint, v as u64); }
     fn emit_u64(v: u64) { self.wr_tagged_u64(es_u64 as uint, v); }
@@ -383,14 +394,18 @@ impl serializer of serialization::serializer for ebml::writer {
     fn emit_tup_elt(_idx: uint, f: fn()) { f() }
 }
 
-type ebml_deserializer = {mut parent: ebml::doc,
-                          mut pos: uint};
+type ebml_deserializer_ = {mut parent: ebml::doc,
+                           mut pos: uint};
+
+enum ebml_deserializer {
+    ebml_deserializer_(ebml_deserializer_)
+}
 
 fn ebml_deserializer(d: ebml::doc) -> ebml_deserializer {
-    {mut parent: d, mut pos: d.start}
+    ebml_deserializer_({mut parent: d, mut pos: d.start})
 }
 
-impl deserializer of serialization::deserializer for ebml_deserializer {
+impl deserializer_priv for ebml_deserializer {
     fn _check_label(lbl: ~str) {
         if self.pos < self.parent.end {
             let {tag: r_tag, doc: r_doc} =
@@ -443,7 +458,9 @@ impl deserializer of serialization::deserializer for ebml_deserializer {
         #debug["_next_uint exp_tag=%? result=%?", exp_tag, r];
         ret r as uint;
     }
+}
 
+impl deserializer of serialization::deserializer for ebml_deserializer {
     fn read_nil() -> () { () }
 
     fn read_u64() -> u64 { ebml::doc_as_u64(self.next_doc(es_u64)) }
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index f8194204626..74707e36a51 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -8,6 +8,7 @@ import io;
 import io::{reader_util, writer_util};
 import map;
 import map::hashmap;
+import map::map;
 import core::vec::extensions;
 
 export json;
@@ -114,13 +115,17 @@ fn to_str(j: json) -> ~str {
     io::with_str_writer(|wr| to_writer(wr, j))
 }
 
-type parser = {
+type parser_ = {
     rdr: io::reader,
     mut ch: char,
     mut line: uint,
     mut col: uint,
 };
 
+enum parser {
+    parser_(parser_)
+}
+
 impl parser for parser {
     fn eof() -> bool { self.ch == -1 as char }
 
@@ -463,12 +468,12 @@ impl parser for parser {
 
 /// Deserializes a json value from an io::reader
 fn from_reader(rdr: io::reader) -> result<json, error> {
-    let parser = {
+    let parser = parser_({
         rdr: rdr,
         mut ch: rdr.read_char(),
         mut line: 1u,
         mut col: 1u,
-    };
+    });
 
     parser.parse()
 }
diff --git a/src/libstd/map.rs b/src/libstd/map.rs
index 90ca5e23372..c285bc06629 100644
--- a/src/libstd/map.rs
+++ b/src/libstd/map.rs
@@ -92,13 +92,19 @@ mod chained {
         absent
     }
 
-    type t<K, V> = @{
+    type hashmap__<K, V> = {
         mut count: uint,
         mut chains: ~[mut chain<K,V>],
         hasher: hashfn<K>,
         eqer: eqfn<K>
     };
 
+    enum hashmap_<K, V> {
+        hashmap_(@hashmap__<K, V>)
+    }
+
+    type t<K, V> = hashmap_<K, V>;
+
     enum search_result<K, V> {
         not_found,
         found_first(uint, @entry<K,V>),
@@ -284,10 +290,10 @@ mod chained {
     }
 
     fn mk<K, V: copy>(hasher: hashfn<K>, eqer: eqfn<K>) -> t<K,V> {
-        let slf: t<K, V> = @{mut count: 0u,
-                             mut chains: chains(initial_capacity),
-                             hasher: hasher,
-                             eqer: eqer};
+        let slf: t<K, V> = hashmap_(@{mut count: 0u,
+                                      mut chains: chains(initial_capacity),
+                                      hasher: hasher,
+                                      eqer: eqer});
         slf
     }
 }
diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs
index a78b6a5f172..f79a95d8ab5 100644
--- a/src/libstd/net_ip.rs
+++ b/src/libstd/net_ip.rs
@@ -148,7 +148,12 @@ mod v4 {
     // the simple, old style numberic representation of
     // ipv4
     type ipv4_rep = { a: u8, b: u8, c: u8, d:u8 };
-    impl x for ipv4_rep {
+
+    trait as_unsafe_u32 {
+        unsafe fn as_u32() -> u32;
+    }
+
+    impl x of as_unsafe_u32 for ipv4_rep {
         // this is pretty dastardly, i know
         unsafe fn as_u32() -> u32 {
             *((ptr::addr_of(self)) as *u32)
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index 31b8841933b..c7dc2d0cdab 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -11,6 +11,7 @@ import future::extensions;
 import result::*;
 import libc::size_t;
 import str::extensions;
+import io::{reader, writer};
 
 // tcp interfaces
 export tcp_socket;
diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs
index ba20ff88e3d..ed9cf5570ce 100644
--- a/src/libstd/serialization.rs
+++ b/src/libstd/serialization.rs
@@ -101,13 +101,21 @@ fn read_to_vec<D: deserializer, T: copy>(d: D, f: fn() -> T) -> ~[T] {
     }
 }
 
-impl serializer_helpers<S: serializer> for S {
+trait serializer_helpers {
+    fn emit_from_vec<T>(v: ~[T], f: fn(T));
+}
+
+impl serializer_helpers<S: serializer> of serializer_helpers for S {
     fn emit_from_vec<T>(v: ~[T], f: fn(T)) {
         emit_from_vec(self, v, f)
     }
 }
 
-impl deserializer_helpers<D: deserializer> for D {
+trait deserializer_helpers {
+    fn read_to_vec<T: copy>(f: fn() -> T) -> ~[T];
+}
+
+impl deserializer_helpers<D: deserializer> of deserializer_helpers for D {
     fn read_to_vec<T: copy>(f: fn() -> T) -> ~[T] {
         read_to_vec(self, f)
     }
diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs
index 1d17ba0dbb4..112a55ab67d 100644
--- a/src/libstd/smallintmap.rs
+++ b/src/libstd/smallintmap.rs
@@ -5,14 +5,19 @@
 import core::option;
 import core::option::{some, none};
 import dvec::{dvec, extensions};
+import map::map;
 
 // FIXME (#2347): Should not be @; there's a bug somewhere in rustc that
 // requires this to be.
-type smallintmap<T: copy> = @{v: dvec<option<T>>};
+type smallintmap_<T: copy> = {v: dvec<option<T>>};
+
+enum smallintmap<T:copy> {
+    smallintmap_(@smallintmap_<T>)
+}
 
 /// Create a smallintmap
 fn mk<T: copy>() -> smallintmap<T> {
-    ret @{v: dvec()};
+    ret smallintmap_(@{v: dvec()});
 }
 
 /**
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 553592b10bd..8680719c9b9 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -65,7 +65,7 @@ fn tzset() {
     rustrt::rust_tzset();
 }
 
-type tm = {
+type tm_ = {
     tm_sec: i32, // seconds after the minute ~[0-60]
     tm_min: i32, // minutes after the hour ~[0-59]
     tm_hour: i32, // hours after midnight ~[0-23]
@@ -80,8 +80,12 @@ type tm = {
     tm_nsec: i32, // nanoseconds
 };
 
+enum tm {
+    tm_(tm_)
+}
+
 fn empty_tm() -> tm {
-    {
+    tm_({
         tm_sec: 0_i32,
         tm_min: 0_i32,
         tm_hour: 0_i32,
@@ -94,7 +98,7 @@ fn empty_tm() -> tm {
         tm_gmtoff: 0_i32,
         tm_zone: ~"",
         tm_nsec: 0_i32,
-    }
+    })
 }
 
 /// Returns the specified time in UTC
@@ -563,7 +567,7 @@ fn strptime(s: ~str, format: ~str) -> result<tm, ~str> {
         }
 
         if pos == len && rdr.eof() {
-            ok({
+            ok(tm_({
                 tm_sec: tm.tm_sec,
                 tm_min: tm.tm_min,
                 tm_hour: tm.tm_hour,
@@ -576,7 +580,7 @@ fn strptime(s: ~str, format: ~str) -> result<tm, ~str> {
                 tm_gmtoff: tm.tm_gmtoff,
                 tm_zone: tm.tm_zone,
                 tm_nsec: tm.tm_nsec,
-            })
+            }))
         } else { result }
     }
 }
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 7a0a0725d95..37e8671facd 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -306,7 +306,13 @@ pure fn class_member_visibility(ci: @class_member) -> visibility {
   }
 }
 
-impl inlined_item_methods for inlined_item {
+trait inlined_item_utils {
+    fn ident() -> ident;
+    fn id() -> ast::node_id;
+    fn accept<E>(e: E, v: visit::vt<E>);
+}
+
+impl inlined_item_methods of inlined_item_utils for inlined_item {
     fn ident() -> ident {
         alt self {
           ii_item(i) { /* FIXME (#2543) */ copy i.ident }
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index a7a6080fb0b..c52617c74bf 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -123,7 +123,34 @@ fn expand(cx: ext_ctxt,
     }
 }
 
-impl helpers for ext_ctxt {
+trait ext_ctxt_helpers {
+    fn helper_path(base_path: @ast::path, helper_name: ~str) -> @ast::path;
+    fn path(span: span, strs: ~[ast::ident]) -> @ast::path;
+    fn path_tps(span: span, strs: ~[ast::ident],
+                tps: ~[@ast::ty]) -> @ast::path;
+    fn ty_path(span: span, strs: ~[ast::ident], tps: ~[@ast::ty]) -> @ast::ty;
+    fn ty_fn(span: span,
+             -input_tys: ~[@ast::ty],
+             -output: @ast::ty) -> @ast::ty;
+    fn ty_nil(span: span) -> @ast::ty;
+    fn expr(span: span, node: ast::expr_) -> @ast::expr;
+    fn var_ref(span: span, name: ast::ident) -> @ast::expr;
+    fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk;
+    fn expr_blk(expr: @ast::expr) -> ast::blk;
+    fn binder_pat(span: span, nm: ast::ident) -> @ast::pat;
+    fn stmt(expr: @ast::expr) -> @ast::stmt;
+    fn alt_stmt(arms: ~[ast::arm], span: span, -v: @ast::expr) -> @ast::stmt;
+    fn lit_str(span: span, s: @~str) -> @ast::expr;
+    fn lit_uint(span: span, i: uint) -> @ast::expr;
+    fn lambda(blk: ast::blk) -> @ast::expr;
+    fn clone_folder() -> fold::ast_fold;
+    fn clone(v: @ast::expr) -> @ast::expr;
+    fn clone_ty(v: @ast::ty) -> @ast::ty;
+    fn clone_ty_param(v: ast::ty_param) -> ast::ty_param;
+    fn at(span: span, expr: @ast::expr) -> @ast::expr;
+}
+
+impl helpers of ext_ctxt_helpers for ext_ctxt {
     fn helper_path(base_path: @ast::path,
                    helper_name: ~str) -> @ast::path {
         let head = vec::init(base_path.idents);
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 3ea088b50e2..58f42152437 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -28,18 +28,29 @@ fn path(id: ident) -> @ast::path {
       types: ~[]}
 }
 
-impl methods for ident {
+trait path_concat {
+    fn +(id: ident) -> @ast::path;
+}
+
+impl methods of path_concat for ident {
     fn +(id: ident) -> @ast::path {
         path(self) + id
     }
 }
 
-impl methods for @ast::path {
+impl methods of path_concat for @ast::path {
     fn +(id: ident) -> @ast::path {
         @{idents: vec::append_one(self.idents, id)
           with *self}
     }
+}
+
+trait append_types {
+    fn add_ty(ty: @ast::ty) -> @ast::path;
+    fn add_tys(+tys: ~[@ast::ty]) -> @ast::path;
+}
 
+impl methods of append_types for @ast::path {
     fn add_ty(ty: @ast::ty) -> @ast::path {
         @{types: vec::append_one(self.types, ty)
           with *self}
@@ -51,7 +62,38 @@ impl methods for @ast::path {
     }
 }
 
-impl ast_builder for ext_ctxt {
+trait ext_ctxt_ast_builder {
+    fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
+        -> ast::ty_param;
+    fn arg(name: ident, ty: @ast::ty) -> ast::arg;
+    fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg;
+    fn expr_block(e: @ast::expr) -> ast::blk;
+    fn fn_decl(+inputs: ~[ast::arg], output: @ast::ty) -> ast::fn_decl;
+    fn item(name: ident, +node: ast::item_) -> @ast::item;
+    fn item_fn_poly(name: ident,
+                    +inputs: ~[ast::arg],
+                    output: @ast::ty,
+                    +ty_params: ~[ast::ty_param],
+                    +body: ast::blk) -> @ast::item;
+    fn item_fn(name: ident,
+               +inputs: ~[ast::arg],
+               output: @ast::ty,
+               +body: ast::blk) -> @ast::item;
+    fn item_enum_poly(name: ident,
+                      +variants: ~[ast::variant],
+                      +ty_params: ~[ast::ty_param]) -> @ast::item;
+    fn item_enum(name: ident, +variants: ~[ast::variant]) -> @ast::item;
+    fn variant(name: ident, +tys: ~[@ast::ty]) -> ast::variant;
+    fn item_mod(name: ident, +items: ~[@ast::item]) -> @ast::item;
+    fn ty_path_ast_builder(path: @ast::path) -> @ast::ty;
+    fn item_ty_poly(name: ident,
+                    ty: @ast::ty,
+                    +params: ~[ast::ty_param]) -> @ast::item;
+    fn item_ty(name: ident, ty: @ast::ty) -> @ast::item;
+    fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty];
+}
+
+impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
     fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
         -> ast::ty_param
     {
@@ -153,7 +195,7 @@ impl ast_builder for ext_ctxt {
                       items: items}))
     }
 
-    fn ty_path(path: @ast::path) -> @ast::ty {
+    fn ty_path_ast_builder(path: @ast::path) -> @ast::ty {
         // FIXME #2886: make sure the node ids are legal.
         @{id: self.next_id(),
           node: ast::ty_path(path, self.next_id()),
@@ -177,6 +219,6 @@ impl ast_builder for ext_ctxt {
     }
 
     fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty] {
-        ty_params.map(|p| self.ty_path(path(p.ident)))
+        ty_params.map(|p| self.ty_path_ast_builder(path(p.ident)))
     }
 }
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index 39084def7e4..091eaf697bb 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -6,7 +6,12 @@ import parse::token;
 
 import pipec::*;
 
-impl proto_parser for parser {
+trait proto_parser {
+    fn parse_proto(id: ident) -> protocol;
+    fn parse_state(proto: protocol);
+}
+
+impl proto_parser of proto_parser for parser {
     fn parse_proto(id: ident) -> protocol {
         let proto = protocol(id);
 
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 4af75fa90e7..eab2c58e50e 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -15,9 +15,9 @@ import pprust::{item_to_str, ty_to_str};
 import ext::base::{mk_ctxt, ext_ctxt};
 import parse;
 import parse::*;
-
 import proto::*;
 
+import ast_builder::append_types;
 import ast_builder::ast_builder;
 import ast_builder::methods;
 import ast_builder::path;
@@ -38,7 +38,7 @@ impl compile for message {
 
             let args_ast = vec::append(
                 ~[cx.arg_mode(@~"pipe",
-                              cx.ty_path(path(this.data_name())
+                              cx.ty_path_ast_builder(path(this.data_name())
                                         .add_tys(cx.ty_vars(this.ty_params))),
                               ast::by_copy)],
                 args_ast);
@@ -64,7 +64,7 @@ impl compile for message {
 
             cx.item_fn_poly(self.name(),
                             args_ast,
-                            cx.ty_path(path(next.data_name())
+                            cx.ty_path_ast_builder(path(next.data_name())
                                       .add_tys(next_tys)),
                             self.get_params(),
                             cx.expr_block(body))
@@ -110,6 +110,11 @@ impl compile for message {
           }
         }
     }
+
+    fn to_ty(cx: ext_ctxt) -> @ast::ty {
+        cx.ty_path_ast_builder(path(self.name)
+          .add_tys(cx.ty_vars(self.ty_params)))
+    }
 }
 
 impl compile for state {
@@ -169,9 +174,9 @@ impl compile for state {
         vec::push(items,
                   cx.item_ty_poly(
                       self.data_name(),
-                      cx.ty_path(
+                      cx.ty_path_ast_builder(
                           (@~"pipes" + @(dir.to_str() + ~"_packet"))
-                          .add_ty(cx.ty_path(
+                          .add_ty(cx.ty_path_ast_builder(
                               (self.proto.name + self.data_name())
                               .add_tys(cx.ty_vars(self.ty_params))))),
                       self.ty_params));
@@ -266,7 +271,12 @@ impl of to_source for @ast::expr {
     }
 }
 
-impl parse_utils for ext_ctxt {
+trait ext_ctxt_parse_utils {
+    fn parse_item(s: ~str) -> @ast::item;
+    fn parse_expr(s: ~str) -> @ast::expr;
+}
+
+impl parse_utils of ext_ctxt_parse_utils for ext_ctxt {
     fn parse_item(s: ~str) -> @ast::item {
         let res = parse::parse_item_from_source_str(
             ~"***protocol expansion***",
@@ -292,3 +302,20 @@ impl parse_utils for ext_ctxt {
             self.parse_sess())
     }
 }
+
+trait two_vector_utils<A, B> {
+    fn zip() -> ~[(A, B)];
+    fn map<C>(f: fn(A, B) -> C) -> ~[C];
+}
+
+impl methods<A: copy, B: copy> of two_vector_utils<A, B> for (~[A], ~[B]) {
+    fn zip() -> ~[(A, B)] {
+        let (a, b) = self;
+        vec::zip(a, b)
+    }
+
+    fn map<C>(f: fn(A, B) -> C) -> ~[C] {
+        let (a, b) = self;
+        vec::map2(a, b, f)
+    }
+}
diff --git a/src/libsyntax/ext/tt/earley_parser.rs b/src/libsyntax/ext/tt/earley_parser.rs
index 3f604aafb3d..152b92a4b53 100644
--- a/src/libsyntax/ext/tt/earley_parser.rs
+++ b/src/libsyntax/ext/tt/earley_parser.rs
@@ -60,6 +60,7 @@ fn count_names(ms: &[matcher]) -> uint {
         }})
 }
 
+#[warn(no_non_implicitly_copyable_typarams)]
 fn new_matcher_pos(ms: ~[matcher], sep: option<token>, lo: uint)
     -> matcher_pos {
     ~{elts: ms, sep: sep, mut idx: 0u, mut up: matcher_pos_up(none),
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 995feff0b70..fb28f952629 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -9,7 +9,21 @@ export parser_attr;
 // extensions, which both begin with token.POUND
 type attr_or_ext = option<either<~[ast::attribute], @ast::expr>>;
 
-impl parser_attr for parser {
+trait parser_attr {
+    fn parse_outer_attrs_or_ext(first_item_attrs: ~[ast::attribute])
+        -> attr_or_ext;
+    fn parse_outer_attributes() -> ~[ast::attribute];
+    fn parse_attribute(style: ast::attr_style) -> ast::attribute;
+    fn parse_attribute_naked(style: ast::attr_style, lo: uint) ->
+        ast::attribute;
+    fn parse_inner_attrs_and_next() ->
+        {inner: ~[ast::attribute], next: ~[ast::attribute]};
+    fn parse_meta_item() -> @ast::meta_item;
+    fn parse_meta_seq() -> ~[@ast::meta_item];
+    fn parse_optional_meta() -> ~[@ast::meta_item];
+}
+
+impl parser_attr of parser_attr for parser {
 
     fn parse_outer_attrs_or_ext(first_item_attrs: ~[ast::attribute])
         -> attr_or_ext
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
index 79ac3aeaf8b..9126bbb3be4 100644
--- a/src/libsyntax/parse/common.rs
+++ b/src/libsyntax/parse/common.rs
@@ -22,9 +22,44 @@ fn token_to_str(reader: reader, ++token: token::token) -> ~str {
     token::to_str(*reader.interner(), token)
 }
 
-// This should be done with traits, once traits work
-impl parser_common for parser {
+trait parser_common {
+    fn unexpected_last(t: token::token) -> !;
+    fn unexpected() -> !;
+    fn expect(t: token::token);
+    fn parse_ident() -> ast::ident;
+    fn parse_path_list_ident() -> ast::path_list_ident;
+    fn parse_value_ident() -> ast::ident;
+    fn eat(tok: token::token) -> bool;
+    // A sanity check that the word we are asking for is a known keyword
+    fn require_keyword(word: ~str);
+    fn token_is_keyword(word: ~str, ++tok: token::token) -> bool;
+    fn is_keyword(word: ~str) -> bool;
+    fn is_any_keyword(tok: token::token) -> bool;
+    fn eat_keyword(word: ~str) -> bool;
+    fn expect_keyword(word: ~str);
+    fn is_restricted_keyword(word: ~str) -> bool;
+    fn check_restricted_keywords();
+    fn check_restricted_keywords_(w: ~str);
+    fn expect_gt();
+    fn parse_seq_to_before_gt<T: copy>(sep: option<token::token>,
+                                       f: fn(parser) -> T) -> ~[T];
+    fn parse_seq_to_gt<T: copy>(sep: option<token::token>,
+                                f: fn(parser) -> T) -> ~[T];
+    fn parse_seq_lt_gt<T: copy>(sep: option<token::token>,
+                                f: fn(parser) -> T) -> spanned<~[T]>;
+    fn parse_seq_to_end<T: copy>(ket: token::token, sep: seq_sep,
+                                 f: fn(parser) -> T) -> ~[T];
+    fn parse_seq_to_before_end<T: copy>(ket: token::token, sep: seq_sep,
+                                        f: fn(parser) -> T) -> ~[T];
+    fn parse_unspanned_seq<T: copy>(bra: token::token,
+                                    ket: token::token,
+                                    sep: seq_sep,
+                                    f: fn(parser) -> T) -> ~[T];
+    fn parse_seq<T: copy>(bra: token::token, ket: token::token, sep: seq_sep,
+                          f: fn(parser) -> T) -> spanned<~[T]>;
+}
 
+impl parser_common of parser_common for parser {
     fn unexpected_last(t: token::token) -> ! {
         self.span_fatal(
             copy self.last_span,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 74210f74d4d..c7687bf2b98 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2188,14 +2188,23 @@ class parser {
         }
     }
 
+    fn token_is_pound_or_doc_comment(++tok: token::token) -> bool {
+        alt tok {
+            token::POUND | token::DOC_COMMENT(_) { true }
+            _ { false }
+        }
+    }
+
     fn parse_single_class_item(vis: visibility)
         -> @class_member {
-        if self.eat_keyword(~"let") {
+        if (self.eat_keyword(~"let") ||
+                self.token_is_keyword(~"mut", copy self.token) ||
+                !self.is_any_keyword(copy self.token)) &&
+                !self.token_is_pound_or_doc_comment(self.token) {
             let a_var = self.parse_instance_var(vis);
             self.expect(token::SEMI);
             ret a_var;
-        }
-        else {
+        } else {
             let m = self.parse_method(vis);
             ret @{node: class_method(m), span: m.span};
         }
@@ -2510,7 +2519,7 @@ class parser {
             self.parse_item_trait()
         } else if self.eat_keyword(~"impl") {
             self.parse_item_impl()
-        } else if self.eat_keyword(~"class") {
+        } else if self.eat_keyword(~"class") || self.eat_keyword(~"struct") {
             self.parse_item_class()
         } else if !self.is_any_keyword(copy self.token)
             && self.look_ahead(1) == token::NOT
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 949b078d8f0..a39b74eaca3 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -313,8 +313,11 @@ fn restricted_keyword_table() -> hashmap<~str, ()> {
         ~"if", ~"iface", ~"impl", ~"import",
         ~"let", ~"log", ~"loop",
         ~"mod", ~"mut",
-        ~"new", ~"owned",
-        ~"pure", ~"ret",
+        ~"new",
+        ~"owned",
+        ~"pure",
+        ~"ret",
+        ~"struct",
         ~"true", ~"trait", ~"type",
         ~"unchecked", ~"unsafe",
         ~"while"
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 1a318d53635..79679279f07 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -103,22 +103,22 @@ fn mk_printer(out: io::writer, linewidth: uint) -> printer {
     let token: ~[mut token] = vec::to_mut(vec::from_elem(n, EOF));
     let size: ~[mut int] = vec::to_mut(vec::from_elem(n, 0));
     let scan_stack: ~[mut uint] = vec::to_mut(vec::from_elem(n, 0u));
-    @{out: out,
-      buf_len: n,
-      mut margin: linewidth as int,
-      mut space: linewidth as int,
-      mut left: 0u,
-      mut right: 0u,
-      token: token,
-      size: size,
-      mut left_total: 0,
-      mut right_total: 0,
-      mut scan_stack: scan_stack,
-      mut scan_stack_empty: true,
-      mut top: 0u,
-      mut bottom: 0u,
-      print_stack: dvec(),
-      mut pending_indentation: 0}
+    printer_(@{out: out,
+               buf_len: n,
+               mut margin: linewidth as int,
+               mut space: linewidth as int,
+               mut left: 0u,
+               mut right: 0u,
+               token: token,
+               size: size,
+               mut left_total: 0,
+               mut right_total: 0,
+               mut scan_stack: scan_stack,
+               mut scan_stack_empty: true,
+               mut top: 0u,
+               mut bottom: 0u,
+               print_stack: dvec(),
+               mut pending_indentation: 0})
 }
 
 
@@ -199,7 +199,7 @@ fn mk_printer(out: io::writer, linewidth: uint) -> printer {
  * the method called 'pretty_print', and the 'PRINT' process is the method
  * called 'print'.
  */
-type printer = @{
+type printer_ = {
     out: io::writer,
     buf_len: uint,
     mut margin: int, // width of lines we're constrained to
@@ -226,6 +226,10 @@ type printer = @{
     mut pending_indentation: int
 };
 
+enum printer {
+    printer_(@printer_)
+}
+
 impl printer for printer {
     fn last_token() -> token { self.token[self.right] }
     // be very careful with this!
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs
index a81b491f23f..0b7b8402970 100644
--- a/src/rustc/driver/driver.rs
+++ b/src/rustc/driver/driver.rs
@@ -1,6 +1,6 @@
 // -*- rust -*-
 import metadata::{creader, cstore, filesearch};
-import session::session;
+import session::{session, session_};
 import syntax::parse;
 import syntax::{ast, codemap};
 import syntax::attr;
@@ -168,7 +168,10 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
                              session::sess_os_to_meta_os(sess.targ_cfg.os),
                              sess.opts.static));
 
-    let { def_map: def_map, exp_map: exp_map, impl_map: impl_map } =
+    let { def_map: def_map,
+          exp_map: exp_map,
+          impl_map: impl_map,
+          trait_map: trait_map } =
         time(time_passes, ~"resolution", ||
              middle::resolve3::resolve_crate(sess, ast_map, crate));
 
@@ -187,6 +190,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
     let (method_map, vtable_map) = time(time_passes, ~"typechecking", ||
                                         typeck::check_crate(ty_cx,
                                                             impl_map,
+                                                            trait_map,
                                                             crate));
 
     time(time_passes, ~"const checking", ||
@@ -516,11 +520,12 @@ fn build_session(sopts: @session::options,
     build_session_(sopts, codemap, demitter, span_diagnostic_handler)
 }
 
-fn build_session_(
-    sopts: @session::options, cm: codemap::codemap,
-    demitter: diagnostic::emitter,
-    span_diagnostic_handler: diagnostic::span_handler
-) -> session {
+fn build_session_(sopts: @session::options,
+                  cm: codemap::codemap,
+                  demitter: diagnostic::emitter,
+                  span_diagnostic_handler: diagnostic::span_handler)
+               -> session {
+
     let target_cfg = build_target_config(sopts, demitter);
     let cstore = cstore::mk_cstore();
     let filesearch = filesearch::mk_filesearch(
@@ -528,19 +533,19 @@ fn build_session_(
         sopts.target_triple,
         sopts.addl_lib_search_paths);
     let warning_settings = lint::mk_warning_settings();
-    @{targ_cfg: target_cfg,
-      opts: sopts,
-      cstore: cstore,
-      parse_sess:
+    session_(@{targ_cfg: target_cfg,
+               opts: sopts,
+               cstore: cstore,
+               parse_sess:
           parse::new_parse_sess_special_handler(span_diagnostic_handler, cm),
-      codemap: cm,
-      // For a library crate, this is always none
-      mut main_fn: none,
-      span_diagnostic: span_diagnostic_handler,
-      filesearch: filesearch,
-      mut building_library: false,
-      working_dir: os::getcwd(),
-      warning_settings: warning_settings}
+               codemap: cm,
+               // For a library crate, this is always none
+               mut main_fn: none,
+               span_diagnostic: span_diagnostic_handler,
+               filesearch: filesearch,
+               mut building_library: false,
+               working_dir: os::getcwd(),
+               warning_settings: warning_settings})
 }
 
 fn parse_pretty(sess: session, &&name: ~str) -> pp_mode {
diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs
index 3697934dbc0..c5643c90be3 100644
--- a/src/rustc/driver/session.rs
+++ b/src/rustc/driver/session.rs
@@ -85,7 +85,7 @@ type options =
 
 type crate_metadata = {name: ~str, data: ~[u8]};
 
-type session = @{targ_cfg: @config,
+type session_ = {targ_cfg: @config,
                  opts: @options,
                  cstore: metadata::cstore::cstore,
                  parse_sess: parse_sess,
@@ -98,6 +98,10 @@ type session = @{targ_cfg: @config,
                  working_dir: ~str,
                  warning_settings: lint::warning_settings};
 
+enum session {
+    session_(@session_)
+}
+
 impl session for session {
     fn span_fatal(sp: span, msg: ~str) -> ! {
         self.span_diagnostic.span_fatal(sp, msg)
diff --git a/src/rustc/metadata/csearch.rs b/src/rustc/metadata/csearch.rs
index 22d70f86eb8..56d6dcab106 100644
--- a/src/rustc/metadata/csearch.rs
+++ b/src/rustc/metadata/csearch.rs
@@ -10,6 +10,7 @@ import syntax::diagnostic::span_handler;
 import syntax::diagnostic::expect;
 import common::*;
 import std::map::hashmap;
+import dvec::{dvec, extensions};
 
 export class_dtor;
 export get_symbol;
@@ -23,6 +24,7 @@ export lookup_method_purity;
 export get_enum_variants;
 export get_impls_for_mod;
 export get_trait_methods;
+export get_method_names_if_trait;
 export each_path;
 export get_type;
 export get_impl_trait;
@@ -140,6 +142,13 @@ fn get_trait_methods(tcx: ty::ctxt, def: ast::def_id) -> @~[ty::method] {
     decoder::get_trait_methods(cdata, def.node, tcx)
 }
 
+fn get_method_names_if_trait(cstore: cstore::cstore, def: ast::def_id)
+                          -> option<@dvec<@~str>> {
+
+    let cdata = cstore::get_crate_data(cstore, def.crate);
+    ret decoder::get_method_names_if_trait(cdata, def.node);
+}
+
 fn get_class_fields(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::field_ty] {
     let cstore = tcx.cstore;
     let cdata = cstore::get_crate_data(cstore, def.crate);
diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs
index 45bdee06070..c9b214134a7 100644
--- a/src/rustc/metadata/decoder.rs
+++ b/src/rustc/metadata/decoder.rs
@@ -2,6 +2,7 @@
 
 import std::{ebml, map};
 import std::map::{hashmap, str_hash};
+import dvec::{dvec, extensions};
 import io::writer_util;
 import syntax::{ast, ast_util};
 import syntax::attr;
@@ -37,6 +38,7 @@ export get_crate_hash;
 export get_crate_vers;
 export get_impls_for_mod;
 export get_trait_methods;
+export get_method_names_if_trait;
 export get_crate_module_paths;
 export def_like;
 export dl_def;
@@ -640,6 +642,23 @@ fn get_trait_methods(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
     @result
 }
 
+// If the item in question is a trait, returns its set of methods. Otherwise,
+// returns none.
+fn get_method_names_if_trait(cdata: cmd, node_id: ast::node_id)
+                          -> option<@dvec<@~str>> {
+
+    let item = lookup_item(node_id, cdata.data);
+    if item_family(item) != 'I' {
+        ret none;
+    }
+
+    let resulting_method_names = @dvec();
+    do ebml::tagged_docs(item, tag_item_trait_method) |method| {
+        (*resulting_method_names).push(item_name(method));
+    }
+    ret some(resulting_method_names);
+}
+
 // Helper function that gets either fields or methods
 fn get_class_members(cdata: cmd, id: ast::node_id,
                      p: fn(char) -> bool) -> ~[ty::field_ty] {
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index 3b7eb8e241c..df0d8e97c0c 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -65,12 +65,16 @@ type decode_ctxt = @{
     maps: maps
 };
 
-type extended_decode_ctxt = @{
+type extended_decode_ctxt_ = {
     dcx: decode_ctxt,
     from_id_range: ast_util::id_range,
     to_id_range: ast_util::id_range
 };
 
+enum extended_decode_ctxt {
+    extended_decode_ctxt_(@extended_decode_ctxt_)
+}
+
 iface tr {
     fn tr(xcx: extended_decode_ctxt) -> self;
 }
@@ -112,9 +116,9 @@ fn decode_inlined_item(cdata: cstore::crate_metadata,
         let ast_dsr = ebml::ebml_deserializer(ast_doc);
         let from_id_range = ast_util::deserialize_id_range(ast_dsr);
         let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range);
-        let xcx = @{dcx: dcx,
-                    from_id_range: from_id_range,
-                    to_id_range: to_id_range};
+        let xcx = extended_decode_ctxt_(@{dcx: dcx,
+                                          from_id_range: from_id_range,
+                                          to_id_range: to_id_range});
         let raw_ii = decode_ast(ast_doc);
         let ii = renumber_ast(xcx, raw_ii);
         ast_map::map_decoded_item(tcx.sess.diagnostic(),
@@ -182,13 +186,23 @@ impl of tr for span {
     }
 }
 
-impl serializer_helpers<S: serializer> for S {
+trait def_id_serializer_helpers {
+    fn emit_def_id(did: ast::def_id);
+}
+
+impl serializer_helpers<S: serializer> of def_id_serializer_helpers for S {
     fn emit_def_id(did: ast::def_id) {
         ast::serialize_def_id(self, did)
     }
 }
 
-impl deserializer_helpers<D: deserializer> for D {
+trait def_id_deserializer_helpers {
+    fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id;
+}
+
+impl deserializer_helpers<D: deserializer> of def_id_deserializer_helpers
+        for D {
+
     fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id {
         let did = ast::deserialize_def_id(self);
         did.tr(xcx)
@@ -370,7 +384,11 @@ fn encode_freevar_entry(ebml_w: ebml::writer, fv: freevar_entry) {
     serialize_freevar_entry(ebml_w, fv)
 }
 
-impl helper for ebml::ebml_deserializer {
+trait ebml_deserializer_helper {
+    fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry;
+}
+
+impl helper of ebml_deserializer_helper for ebml::ebml_deserializer {
     fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry {
         let fv = deserialize_freevar_entry(self);
         fv.tr(xcx)
@@ -386,7 +404,11 @@ impl of tr for freevar_entry {
 // ______________________________________________________________________
 // Encoding and decoding of method_map_entry
 
-impl helper for ebml::ebml_deserializer {
+trait read_method_map_entry_helper {
+    fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry;
+}
+
+impl helper of read_method_map_entry_helper for ebml::ebml_deserializer {
     fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry {
         let mme = deserialize_method_map_entry(self);
         {derefs: mme.derefs, origin: mme.origin.tr(xcx)}
@@ -412,7 +434,11 @@ impl of tr for method_origin {
 // ______________________________________________________________________
 // Encoding and decoding of borrow
 
-impl helper for ebml::ebml_deserializer {
+trait read_borrow_helper {
+    fn read_borrow(xcx: extended_decode_ctxt) -> ty::borrow;
+}
+
+impl helper of read_borrow_helper for ebml::ebml_deserializer {
     fn read_borrow(xcx: extended_decode_ctxt) -> ty::borrow {
         let borrow = ty::deserialize_borrow(self);
         {scope_id: xcx.tr_id(borrow.scope_id),
@@ -478,7 +504,12 @@ fn encode_vtable_origin(ecx: @e::encode_ctxt,
 
 }
 
-impl helpers for ebml::ebml_deserializer {
+trait vtable_deserialization_helpers {
+    fn read_vtable_res(xcx: extended_decode_ctxt) -> typeck::vtable_res;
+    fn read_vtable_origin(xcx: extended_decode_ctxt) -> typeck::vtable_origin;
+}
+
+impl helpers of vtable_deserialization_helpers for ebml::ebml_deserializer {
     fn read_vtable_res(xcx: extended_decode_ctxt) -> typeck::vtable_res {
         @self.read_to_vec(|| self.read_vtable_origin(xcx) )
     }
@@ -530,7 +561,11 @@ impl helpers for ebml::ebml_deserializer {
 // ______________________________________________________________________
 // Encoding and decoding the side tables
 
-impl helpers for @e::encode_ctxt {
+trait get_ty_str_ctxt {
+    fn ty_str_ctxt() -> @tyencode::ctxt;
+}
+
+impl helpers of get_ty_str_ctxt for @e::encode_ctxt {
     fn ty_str_ctxt() -> @tyencode::ctxt {
         @{diag: self.tcx.sess.diagnostic(),
           ds: e::def_to_str,
@@ -540,7 +575,14 @@ impl helpers for @e::encode_ctxt {
     }
 }
 
-impl helpers for ebml::writer {
+trait ebml_writer_helpers {
+    fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t);
+    fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]);
+    fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds);
+    fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty);
+}
+
+impl helpers of ebml_writer_helpers for ebml::writer {
     fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t) {
         e::write_type(ecx, self, ty)
     }
@@ -572,7 +614,12 @@ impl helpers for ebml::writer {
     }
 }
 
-impl writer for ebml::writer {
+trait write_tag_and_id {
+    fn tag(tag_id: c::astencode_tag, f: fn());
+    fn id(id: ast::node_id);
+}
+
+impl writer of write_tag_and_id for ebml::writer {
     fn tag(tag_id: c::astencode_tag, f: fn()) {
         do self.wr_tag(tag_id as uint) { f() }
     }
@@ -724,7 +771,13 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
     }
 }
 
-impl decoder for ebml::doc {
+trait doc_decoder_helpers {
+    fn as_int() -> int;
+    fn [](tag: c::astencode_tag) -> ebml::doc;
+    fn opt_child(tag: c::astencode_tag) -> option<ebml::doc>;
+}
+
+impl decoder of doc_decoder_helpers for ebml::doc {
     fn as_int() -> int { ebml::doc_as_u64(self) as int }
     fn [](tag: c::astencode_tag) -> ebml::doc {
         ebml::get_doc(self, tag as uint)
@@ -734,7 +787,17 @@ impl decoder for ebml::doc {
     }
 }
 
-impl decoder for ebml::ebml_deserializer {
+trait ebml_deserializer_decoder_helpers {
+    fn read_ty(xcx: extended_decode_ctxt) -> ty::t;
+    fn read_tys(xcx: extended_decode_ctxt) -> ~[ty::t];
+    fn read_bounds(xcx: extended_decode_ctxt) -> @~[ty::param_bound];
+    fn read_ty_param_bounds_and_ty(xcx: extended_decode_ctxt)
+                                -> ty::ty_param_bounds_and_ty;
+}
+
+impl decoder of ebml_deserializer_decoder_helpers
+        for ebml::ebml_deserializer {
+
     fn read_ty(xcx: extended_decode_ctxt) -> ty::t {
         // Note: regions types embed local node ids.  In principle, we
         // should translate these node ids into the new decode
diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs
index 4d5fb239d9e..4bbbb2bcb6c 100644
--- a/src/rustc/middle/borrowck.rs
+++ b/src/rustc/middle/borrowck.rs
@@ -169,17 +169,18 @@ fn check_crate(tcx: ty::ctxt,
                method_map: typeck::method_map,
                last_use_map: liveness::last_use_map,
                crate: @ast::crate) -> (root_map, mutbl_map) {
-    let bccx = @{tcx: tcx,
-                 method_map: method_map,
-                 last_use_map: last_use_map,
-                 binding_map: int_hash(),
-                 root_map: root_map(),
-                 mutbl_map: int_hash(),
-                 mut loaned_paths_same: 0,
-                 mut loaned_paths_imm: 0,
-                 mut stable_paths: 0,
-                 mut req_pure_paths: 0,
-                 mut guaranteed_paths: 0};
+
+    let bccx = borrowck_ctxt_(@{tcx: tcx,
+                                method_map: method_map,
+                                last_use_map: last_use_map,
+                                binding_map: int_hash(),
+                                root_map: root_map(),
+                                mutbl_map: int_hash(),
+                                mut loaned_paths_same: 0,
+                                mut loaned_paths_imm: 0,
+                                mut stable_paths: 0,
+                                mut req_pure_paths: 0,
+                                mut guaranteed_paths: 0});
 
     let req_maps = gather_loans::gather_loans(bccx, crate);
     check_loans::check_loans(bccx, req_maps, crate);
@@ -210,7 +211,7 @@ fn check_crate(tcx: ty::ctxt,
 // ----------------------------------------------------------------------
 // Type definitions
 
-type borrowck_ctxt = @{tcx: ty::ctxt,
+type borrowck_ctxt_ = {tcx: ty::ctxt,
                        method_map: typeck::method_map,
                        last_use_map: liveness::last_use_map,
                        binding_map: binding_map,
@@ -224,6 +225,10 @@ type borrowck_ctxt = @{tcx: ty::ctxt,
                        mut req_pure_paths: uint,
                        mut guaranteed_paths: uint};
 
+enum borrowck_ctxt {
+    borrowck_ctxt_(@borrowck_ctxt_)
+}
+
 // a map mapping id's of expressions of gc'd type (@T, @[], etc) where
 // the box needs to be kept live to the id of the scope for which they
 // must stay live.
@@ -365,7 +370,11 @@ impl of ast_node for @ast::pat {
     fn span() -> span { self.span }
 }
 
-impl methods for ty::ctxt {
+trait get_type_for_node {
+    fn ty<N: ast_node>(node: N) -> ty::t;
+}
+
+impl methods of get_type_for_node for ty::ctxt {
     fn ty<N: ast_node>(node: N) -> ty::t {
         ty::node_id_to_type(self, node.id())
     }
diff --git a/src/rustc/middle/borrowck/loan.rs b/src/rustc/middle/borrowck/loan.rs
index 5549ca53eb2..ee902885562 100644
--- a/src/rustc/middle/borrowck/loan.rs
+++ b/src/rustc/middle/borrowck/loan.rs
@@ -6,17 +6,21 @@ export public_methods;
 
 impl public_methods for borrowck_ctxt {
     fn loan(cmt: cmt, mutbl: ast::mutability) -> @dvec<loan> {
-        let lc = @{bccx: self, loans: @dvec()};
+        let lc = loan_ctxt_(@{bccx: self, loans: @dvec()});
         lc.loan(cmt, mutbl);
         ret lc.loans;
     }
 }
 
-type loan_ctxt = @{
+type loan_ctxt_ = {
     bccx: borrowck_ctxt,
     loans: @dvec<loan>
 };
 
+enum loan_ctxt {
+    loan_ctxt_(@loan_ctxt_)
+}
+
 impl loan_methods for loan_ctxt {
     fn ok_with_loan_of(cmt: cmt,
                        mutbl: ast::mutability) {
diff --git a/src/rustc/middle/lint.rs b/src/rustc/middle/lint.rs
index 08eabe493c7..f5ca8cfd543 100644
--- a/src/rustc/middle/lint.rs
+++ b/src/rustc/middle/lint.rs
@@ -162,14 +162,17 @@ fn get_warning_settings_level(settings: warning_settings,
 // This is kind of unfortunate. It should be somewhere else, or we should use
 // a persistent data structure...
 fn clone_lint_modes(modes: lint_modes) -> lint_modes {
-    @{v: copy modes.v}
+    std::smallintmap::smallintmap_(@{v: copy modes.v})
 }
 
-type ctxt = {dict: lint_dict,
-             curr: lint_modes,
-             is_default: bool,
-             sess: session};
+type ctxt_ = {dict: lint_dict,
+              curr: lint_modes,
+              is_default: bool,
+              sess: session};
 
+enum ctxt {
+    ctxt_(ctxt_)
+}
 
 impl methods for ctxt {
     fn get_level(lint: lint) -> level {
@@ -216,9 +219,10 @@ impl methods for ctxt {
                             // we do multiple unneeded copies of the map
                             // if many attributes are set, but this shouldn't
                             // actually be a problem...
-                            new_ctxt = {is_default: false,
-                                        curr: clone_lint_modes(new_ctxt.curr)
-                                        with new_ctxt};
+                            new_ctxt =
+                                ctxt_({is_default: false,
+                                       curr: clone_lint_modes(new_ctxt.curr)
+                                      with *new_ctxt});
                             new_ctxt.set_level(lint, new_level);
                           }
                         }
@@ -271,10 +275,10 @@ fn build_settings_item(i: @ast::item, &&cx: ctxt, v: visit::vt<ctxt>) {
 
 fn build_settings_crate(sess: session::session, crate: @ast::crate) {
 
-    let cx = {dict: get_lint_dict(),
-              curr: std::smallintmap::mk(),
-              is_default: true,
-              sess: sess};
+    let cx = ctxt_({dict: get_lint_dict(),
+                    curr: std::smallintmap::mk(),
+                    is_default: true,
+                    sess: sess});
 
     // Install defaults.
     for cx.dict.each |_k, spec| { cx.set_level(spec.lint, spec.default); }
@@ -291,7 +295,7 @@ fn build_settings_crate(sess: session::session, crate: @ast::crate) {
             sess.warning_settings.default_settings.insert(k, v);
         }
 
-        let cx = {is_default: true with cx};
+        let cx = ctxt_({is_default: true with *cx});
 
         let visit = visit::mk_vt(@{
             visit_item: build_settings_item
diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs
index 7403d568d5a..4168f2bbe89 100644
--- a/src/rustc/middle/region.rs
+++ b/src/rustc/middle/region.rs
@@ -426,7 +426,7 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
 type region_paramd_items = hashmap<ast::node_id, ()>;
 type dep_map = hashmap<ast::node_id, @dvec<ast::node_id>>;
 
-type determine_rp_ctxt = @{
+type determine_rp_ctxt_ = {
     sess: session,
     ast_map: ast_map::map,
     def_map: resolve::def_map,
@@ -442,6 +442,10 @@ type determine_rp_ctxt = @{
     mut anon_implies_rp: bool
 };
 
+enum determine_rp_ctxt {
+    determine_rp_ctxt_(@determine_rp_ctxt_)
+}
+
 impl methods for determine_rp_ctxt {
     fn add_rp(id: ast::node_id) {
         assert id != 0;
@@ -608,14 +612,14 @@ fn determine_rp_in_crate(sess: session,
                          ast_map: ast_map::map,
                          def_map: resolve::def_map,
                          crate: @ast::crate) -> region_paramd_items {
-    let cx = @{sess: sess,
-               ast_map: ast_map,
-               def_map: def_map,
-               region_paramd_items: int_hash(),
-               dep_map: int_hash(),
-               worklist: dvec(),
-               mut item_id: 0,
-               mut anon_implies_rp: false};
+    let cx = determine_rp_ctxt_(@{sess: sess,
+                                  ast_map: ast_map,
+                                  def_map: def_map,
+                                  region_paramd_items: int_hash(),
+                                  dep_map: int_hash(),
+                                  worklist: dvec(),
+                                  mut item_id: 0,
+                                  mut anon_implies_rp: false});
 
     // gather up the base set, worklist and dep_map:
     let visitor = visit::mk_vt(@{
diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs
index 7a021549b92..04a7448f798 100644
--- a/src/rustc/middle/resolve3.rs
+++ b/src/rustc/middle/resolve3.rs
@@ -1,5 +1,6 @@
 import driver::session::session;
-import metadata::csearch::{each_path, get_impls_for_mod, lookup_defs};
+import metadata::csearch::{each_path, get_impls_for_mod};
+import metadata::csearch::{get_method_names_if_trait, lookup_defs};
 import metadata::cstore::find_use_stmt_cnum;
 import metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
 import middle::lint::{error, ignore, level, unused_imports, warn};
@@ -59,6 +60,9 @@ type ImplScope = @~[@Impl];
 type ImplScopes = @list<ImplScope>;
 type ImplMap = hashmap<node_id,ImplScopes>;
 
+// Trait method resolution
+type TraitMap = @hashmap<node_id,@dvec<def_id>>;
+
 // Export mapping
 type Export = { reexp: bool, id: def_id };
 type ExportMap = hashmap<node_id, ~[Export]>;
@@ -599,6 +603,8 @@ class Resolver {
 
     let unused_import_lint_level: level;
 
+    let trait_info: hashmap<def_id,@hashmap<Atom,()>>;
+
     // The number of imports that are currently unresolved.
     let mut unresolved_imports: uint;
 
@@ -617,6 +623,9 @@ class Resolver {
     // allowed to access private names of any module.
     let mut xray_context: XrayFlag;
 
+    // The trait that the current context can refer to.
+    let mut current_trait_ref: option<def_id>;
+
     // The atom for the keyword "self".
     let self_atom: Atom;
 
@@ -629,6 +638,7 @@ class Resolver {
     let def_map: DefMap;
     let impl_map: ImplMap;
     let export_map: ExportMap;
+    let trait_map: TraitMap;
 
     new(session: session, ast_map: ASTMap, crate: @crate) {
         self.session = session;
@@ -646,12 +656,16 @@ class Resolver {
 
         self.unused_import_lint_level = unused_import_lint_level(session);
 
+        self.trait_info = new_def_hash();
+
         self.unresolved_imports = 0u;
 
         self.current_module = (*self.graph_root).get_module();
         self.value_ribs = @dvec();
         self.type_ribs = @dvec();
+
         self.xray_context = NoXray;
+        self.current_trait_ref = none;
 
         self.self_atom = (*self.atom_table).intern(@~"self");
         self.primitive_type_table = @PrimitiveTypeTable(self.atom_table);
@@ -661,6 +675,7 @@ class Resolver {
         self.def_map = int_hash();
         self.impl_map = int_hash();
         self.export_map = int_hash();
+        self.trait_map = @int_hash();
     }
 
     /// The main name resolution procedure.
@@ -930,14 +945,34 @@ class Resolver {
                 visit_item(item, new_parent, visitor);
             }
 
-            item_trait(*) {
-                (*name_bindings).define_type(def_ty(local_def(item.id)));
+            item_trait(_, methods) {
+                // Add the names of all the methods to the trait info.
+                let method_names = @atom_hashmap();
+                for methods.each |method| {
+                    let atom;
+                    alt method {
+                        required(required_method) {
+                            atom = (*self.atom_table).intern
+                                (required_method.ident);
+                        }
+                        provided(provided_method) {
+                            atom = (*self.atom_table).intern
+                                (provided_method.ident);
+                        }
+                    }
+                    (*method_names).insert(atom, ());
+                }
+
+                let def_id = local_def(item.id);
+                self.trait_info.insert(def_id, method_names);
+
+                (*name_bindings).define_type(def_ty(def_id));
                 visit_item(item, new_parent, visitor);
             }
 
-          item_mac(*) {
-            fail ~"item macros unimplemented"
-          }
+            item_mac(*) {
+                fail ~"item macros unimplemented"
+            }
         }
     }
 
@@ -1300,6 +1335,34 @@ class Resolver {
                         def_ty(def_id) {
                             #debug("(building reduced graph for external \
                                     crate) building type %s", final_ident);
+
+                            // If this is a trait, add all the method names
+                            // to the trait info.
+
+                            alt get_method_names_if_trait(self.session.cstore,
+                                                          def_id) {
+                                none {
+                                    // Nothing to do.
+                                }
+                                some(method_names) {
+                                    let interned_method_names =
+                                        @atom_hashmap();
+                                    for method_names.each |method_name| {
+                                        #debug("(building reduced graph for \
+                                                 external crate) ... adding \
+                                                 trait method '%?'",
+                                               method_name);
+                                        let atom =
+                                            (*self.atom_table).intern
+                                                (method_name);
+                                        (*interned_method_names).insert(atom,
+                                                                        ());
+                                    }
+                                    self.trait_info.insert
+                                        (def_id, interned_method_names);
+                                }
+                            }
+
                             (*child_name_bindings).define_type(def);
                         }
                         def_class(def_id) {
@@ -2724,7 +2787,9 @@ class Resolver {
 
         // Move down in the graph.
         alt name {
-            none { /* Nothing to do. */ }
+            none {
+                // Nothing to do.
+            }
             some(name) {
                 alt orig_module.children.find(name) {
                     none {
@@ -2903,6 +2968,7 @@ class Resolver {
 
             item_impl(type_parameters, interface_reference, self_type,
                       methods) {
+
                 self.resolve_implementation(item.id,
                                             item.span,
                                             type_parameters,
@@ -2922,8 +2988,7 @@ class Resolver {
                 // Create a new rib for the interface-wide type parameters.
                 do self.with_type_parameter_rib
                         (HasTypeParameters(&type_parameters, item.id, 0u,
-                                           NormalRibKind))
-                        || {
+                                           NormalRibKind)) {
 
                     self.resolve_type_parameters(type_parameters, visitor);
 
@@ -2939,8 +3004,7 @@ class Resolver {
                                 (HasTypeParameters(&ty_m.tps,
                                                    item.id,
                                                    type_parameters.len(),
-                                                   NormalRibKind))
-                            || {
+                                                   NormalRibKind)) {
 
                                 // Resolve the method-specific type
                                 // parameters.
@@ -3318,13 +3382,13 @@ class Resolver {
         let borrowed_type_parameters: &~[ty_param] = &type_parameters;
         do self.with_type_parameter_rib(HasTypeParameters
                                         (borrowed_type_parameters, id, 0u,
-                                         NormalRibKind))
-                || {
+                                         NormalRibKind)) {
 
             // Resolve the type parameters.
             self.resolve_type_parameters(type_parameters, visitor);
 
             // Resolve the interface reference, if necessary.
+            let original_trait_ref = self.current_trait_ref;
             alt interface_reference {
                 none {
                     // Nothing to do.
@@ -3339,6 +3403,9 @@ class Resolver {
                         }
                         some(def) {
                             self.record_def(interface_reference.ref_id, def);
+
+                            // Record the current trait reference.
+                            self.current_trait_ref = some(def_id_of_def(def));
                         }
                     }
                 }
@@ -3364,6 +3431,9 @@ class Resolver {
                                       NoCaptureClause,
                                       visitor);
             }
+
+            // Restore the original trait reference.
+            self.current_trait_ref = original_trait_ref;
         }
     }
 
@@ -3828,9 +3898,10 @@ class Resolver {
                                 ret ImportNameDefinition(def);
                             }
                             none {
-                                fail ~"target for namespace doesn't refer to \
-                                      bindings that contain a definition for \
-                                      that namespace!";
+                                // This can happen with external impls, due to
+                                // the imperfect way we read the metadata.
+
+                                ret NoNameDefinition;
                             }
                         }
                     }
@@ -4040,6 +4111,11 @@ class Resolver {
 
         self.record_impls_for_expr_if_necessary(expr);
 
+        // Then record candidate traits for this expression if it could result
+        // in the invocation of a method call.
+
+        self.record_candidate_traits_for_expr_if_necessary(expr);
+
         // Next, resolve the node.
         alt expr.node {
             // The interpretation of paths depends on whether the path has
@@ -4101,6 +4177,109 @@ class Resolver {
         }
     }
 
+    fn record_candidate_traits_for_expr_if_necessary(expr: @expr) {
+        alt expr.node {
+            expr_field(_, ident, _) {
+                let atom = (*self.atom_table).intern(ident);
+                let traits = self.search_for_traits_containing_method(atom);
+                self.trait_map.insert(expr.id, traits);
+            }
+            _ {
+                // Nothing to do.
+                //
+                // XXX: Handle more here... operator overloading, placement
+                // new, etc.
+            }
+        }
+    }
+
+    fn search_for_traits_containing_method(name: Atom) -> @dvec<def_id> {
+        let found_traits = @dvec();
+        let mut search_module = self.current_module;
+        loop {
+            // Look for the current trait.
+            alt copy self.current_trait_ref {
+                some(trait_def_id) {
+                    self.add_trait_info_if_containing_method(found_traits,
+                                                             trait_def_id,
+                                                             name);
+                }
+                none {
+                    // Nothing to do.
+                }
+            }
+
+            // Look for trait children.
+            for search_module.children.each |_name, child_name_bindings| {
+                alt child_name_bindings.def_for_namespace(TypeNS) {
+                    some(def_ty(trait_def_id)) {
+                        self.add_trait_info_if_containing_method(found_traits,
+                                                                 trait_def_id,
+                                                                 name);
+                    }
+                    some(_) | none {
+                        // Continue.
+                    }
+                }
+            }
+
+            // Look for imports.
+            for search_module.import_resolutions.each
+                    |_atom, import_resolution| {
+
+                alt import_resolution.target_for_namespace(TypeNS) {
+                    none {
+                        // Continue.
+                    }
+                    some(target) {
+                        alt target.bindings.def_for_namespace(TypeNS) {
+                            some(def_ty(trait_def_id)) {
+                                self.add_trait_info_if_containing_method
+                                    (found_traits, trait_def_id, name);
+                            }
+                            some(_) | none {
+                                // Continue.
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Move to the next parent.
+            alt search_module.parent_link {
+                NoParentLink {
+                    // Done.
+                    break;
+                }
+                ModuleParentLink(parent_module, _) |
+                BlockParentLink(parent_module, _) {
+                    search_module = parent_module;
+                }
+            }
+        }
+
+        ret found_traits;
+    }
+
+    fn add_trait_info_if_containing_method(found_traits: @dvec<def_id>,
+                                           trait_def_id: def_id,
+                                           name: Atom) {
+
+        alt self.trait_info.find(trait_def_id) {
+            some(trait_info) if trait_info.contains_key(name) {
+                #debug("(adding trait info if containing method) found trait \
+                        %d:%d for method '%s'",
+                       trait_def_id.crate,
+                       trait_def_id.node,
+                       *(*self.atom_table).atom_to_str(name));
+                (*found_traits).push(trait_def_id);
+            }
+            some(_) | none {
+                // Continue.
+            }
+        }
+    }
+
     fn record_def(node_id: node_id, def: def) {
         #debug("(recording def) recording %? for %?", def, node_id);
         self.def_map.insert(node_id, def);
@@ -4310,14 +4489,18 @@ class Resolver {
 
 /// Entry point to crate resolution.
 fn resolve_crate(session: session, ast_map: ASTMap, crate: @crate)
-              -> { def_map: DefMap, exp_map: ExportMap, impl_map: ImplMap } {
+              -> { def_map: DefMap,
+                   exp_map: ExportMap,
+                   impl_map: ImplMap,
+                   trait_map: TraitMap } {
 
     let resolver = @Resolver(session, ast_map, crate);
     (*resolver).resolve(resolver);
     ret {
         def_map: resolver.def_map,
         exp_map: resolver.export_map,
-        impl_map: resolver.impl_map
+        impl_map: resolver.impl_map,
+        trait_map: resolver.trait_map
     };
 }
 
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 256c3b0dd11..24acfcecdf7 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -94,7 +94,11 @@ class icx_popper {
     }
 }
 
-impl ccx_icx for @crate_ctxt {
+trait get_insn_ctxt {
+    fn insn_ctxt(s: ~str) -> icx_popper;
+}
+
+impl ccx_icx of get_insn_ctxt for @crate_ctxt {
     fn insn_ctxt(s: ~str) -> icx_popper {
         #debug("new insn_ctxt: %s", s);
         if self.sess.count_llvm_insns() {
@@ -104,13 +108,13 @@ impl ccx_icx for @crate_ctxt {
     }
 }
 
-impl bcx_icx for block {
+impl bcx_icx of get_insn_ctxt for block {
     fn insn_ctxt(s: ~str) -> icx_popper {
         self.ccx().insn_ctxt(s)
     }
 }
 
-impl fcx_icx for fn_ctxt {
+impl fcx_icx of get_insn_ctxt for fn_ctxt {
     fn insn_ctxt(s: ~str) -> icx_popper {
         self.ccx.insn_ctxt(s)
     }
diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs
index 13f5b2f8470..2f460e2678e 100644
--- a/src/rustc/middle/trans/common.rs
+++ b/src/rustc/middle/trans/common.rs
@@ -348,19 +348,23 @@ type scope_info = {
     mut landing_pad: option<BasicBlockRef>,
 };
 
-impl node_info for @ast::expr {
+trait get_node_info {
+    fn info() -> option<node_info>;
+}
+
+impl node_info of get_node_info for @ast::expr {
     fn info() -> option<node_info> {
         some({id: self.id, span: self.span})
     }
 }
 
-impl node_info for ast::blk {
+impl node_info of get_node_info for ast::blk {
     fn info() -> option<node_info> {
         some({id: self.node.id, span: self.span})
     }
 }
 
-impl node_info for option<@ast::expr> {
+impl node_info of get_node_info for option<@ast::expr> {
     fn info() -> option<node_info> {
         self.chain(|s| s.info())
     }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 0ff07554505..1cf46ba9b32 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -165,6 +165,7 @@ export terr_sorts, terr_vec, terr_str, terr_record_size, terr_tuple_size;
 export terr_regions_differ, terr_mutability, terr_purity_mismatch;
 export terr_proto_mismatch;
 export terr_ret_style_mismatch;
+export purity_to_str;
 
 // Data types
 
@@ -441,7 +442,11 @@ impl of vid for region_vid {
     fn to_str() -> ~str { #fmt["<R%u>", self.to_uint()] }
 }
 
-impl of to_str::to_str for purity {
+trait purity_to_str {
+    fn to_str() -> ~str;
+}
+
+impl of purity_to_str for purity {
     fn to_str() -> ~str {
         purity_to_str(self)
     }
@@ -2359,7 +2364,8 @@ fn type_err_to_str(cx: ctxt, err: type_err) -> ~str {
             ~" function was expected";
       }
       terr_purity_mismatch(f1, f2) {
-        ret #fmt["expected %s fn but found %s fn", f1.to_str(), f2.to_str()];
+        ret #fmt["expected %s fn but found %s fn",
+                 purity_to_str(f1), purity_to_str(f2)];
       }
       terr_proto_mismatch(e, a) {
         ret #fmt["closure protocol mismatch (%s vs %s)",
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index 51f87c697a5..9d4968ef443 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -154,10 +154,16 @@ type ty_param_substs_and_ty = {substs: ty::substs, ty: ty::t};
 
 type ty_table = hashmap<ast::def_id, ty::t>;
 
-type crate_ctxt = {impl_map: resolve::impl_map,
-                   method_map: method_map,
-                   vtable_map: vtable_map,
-                   tcx: ty::ctxt};
+type crate_ctxt_ = {impl_map: resolve::impl_map,
+                    trait_map: resolve3::TraitMap,
+                    method_map: method_map,
+                    vtable_map: vtable_map,
+                    coherence_info: @coherence::CoherenceInfo,
+                    tcx: ty::ctxt};
+
+enum crate_ctxt {
+    crate_ctxt_(crate_ctxt_)
+}
 
 // Functions that write types into the node type table
 fn write_ty_to_tcx(tcx: ty::ctxt, node_id: ast::node_id, ty: ty::t) {
@@ -284,17 +290,20 @@ fn check_for_main_fn(ccx: @crate_ctxt) {
     }
 }
 
-fn check_crate(tcx: ty::ctxt, impl_map: resolve::impl_map,
-               crate: @ast::crate) -> (method_map, vtable_map) {
-    let ccx = @{impl_map: impl_map,
-                method_map: std::map::int_hash(),
-                vtable_map: std::map::int_hash(),
-                tcx: tcx};
+fn check_crate(tcx: ty::ctxt,
+               impl_map: resolve::impl_map,
+               trait_map: resolve3::TraitMap,
+               crate: @ast::crate)
+            -> (method_map, vtable_map) {
+
+    let ccx = @crate_ctxt_({impl_map: impl_map,
+                            trait_map: trait_map,
+                            method_map: std::map::int_hash(),
+                            vtable_map: std::map::int_hash(),
+                            coherence_info: @coherence::CoherenceInfo(),
+                            tcx: tcx});
     collect::collect_item_types(ccx, crate);
-
-    if tcx.sess.coherence() {
-        coherence::check_coherence(ccx, crate);
-    }
+    coherence::check_coherence(ccx, crate);
 
     check::check_item_types(ccx, crate);
     check_for_main_fn(ccx);
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index bf2e4cb0e33..5a8d0b15619 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -76,7 +76,7 @@ import syntax::ast::ty_i;
 import typeck::infer::{unify_methods}; // infcx.set()
 import typeck::infer::{resolve_type, force_tvar};
 
-type fn_ctxt =
+type fn_ctxt_ =
     // var_bindings, locals and next_var_id are shared
     // with any nested functions that capture the environment
     // (and with any functions whose environment is being captured).
@@ -111,30 +111,39 @@ type fn_ctxt =
 
      ccx: @crate_ctxt};
 
+enum fn_ctxt {
+    fn_ctxt_(fn_ctxt_)
+}
+
 // Used by check_const and check_enum_variants
 fn blank_fn_ctxt(ccx: @crate_ctxt, rty: ty::t,
                  region_bnd: ast::node_id) -> @fn_ctxt {
 // It's kind of a kludge to manufacture a fake function context
 // and statement context, but we might as well do write the code only once
-    @{self_ty: none,
-      ret_ty: rty,
-      indirect_ret_ty: none,
-      purity: ast::pure_fn,
-      infcx: infer::new_infer_ctxt(ccx.tcx),
-      locals: int_hash(),
-      mut region_lb: region_bnd,
-      mut region_ub: region_bnd,
-      in_scope_regions: @nil,
-      node_types: smallintmap::mk(),
-      node_type_substs: map::int_hash(),
-      ccx: ccx}
+    @fn_ctxt_({self_ty: none,
+               ret_ty: rty,
+               indirect_ret_ty: none,
+               purity: ast::pure_fn,
+               infcx: infer::new_infer_ctxt(ccx.tcx),
+               locals: int_hash(),
+               mut region_lb: region_bnd,
+               mut region_ub: region_bnd,
+               in_scope_regions: @nil,
+               node_types: smallintmap::mk(),
+               node_type_substs: map::int_hash(),
+               ccx: ccx})
 }
 
 // a list of mapping from in-scope-region-names ("isr") to the
 // corresponding ty::region
 type isr_alist = @list<(ty::bound_region, ty::region)>;
 
-impl methods for isr_alist {
+trait get_and_find_region {
+    fn get(br: ty::bound_region) -> ty::region;
+    fn find(br: ty::bound_region) -> option<ty::region>;
+}
+
+impl methods of get_and_find_region for isr_alist {
     fn get(br: ty::bound_region) -> ty::region {
         option::get(self.find(br))
     }
@@ -227,18 +236,18 @@ fn check_fn(ccx: @crate_ctxt,
             }
         } else { none };
 
-        @{self_ty: self_ty,
-          ret_ty: ret_ty,
-          indirect_ret_ty: indirect_ret_ty,
-          purity: purity,
-          infcx: infcx,
-          locals: locals,
-          mut region_lb: body.node.id,
-          mut region_ub: body.node.id,
-          in_scope_regions: isr,
-          node_types: node_types,
-          node_type_substs: node_type_substs,
-          ccx: ccx}
+        @fn_ctxt_({self_ty: self_ty,
+                   ret_ty: ret_ty,
+                   indirect_ret_ty: indirect_ret_ty,
+                   purity: purity,
+                   infcx: infcx,
+                   locals: locals,
+                   mut region_lb: body.node.id,
+                   mut region_ub: body.node.id,
+                   in_scope_regions: isr,
+                   node_types: node_types,
+                   node_type_substs: node_type_substs,
+                   ccx: ccx})
     };
 
     gather_locals(fcx, decl, body, arg_tys);
@@ -1787,8 +1796,8 @@ fn check_block_no_value(fcx: @fn_ctxt, blk: ast::blk) -> bool {
 
 fn check_block(fcx0: @fn_ctxt, blk: ast::blk) -> bool {
     let fcx = alt blk.node.rules {
-      ast::unchecked_blk { @{purity: ast::impure_fn with *fcx0} }
-      ast::unsafe_blk { @{purity: ast::unsafe_fn with *fcx0} }
+      ast::unchecked_blk { @fn_ctxt_({purity: ast::impure_fn with **fcx0}) }
+      ast::unsafe_blk { @fn_ctxt_({purity: ast::unsafe_fn with **fcx0}) }
       ast::default_blk { fcx0 }
     };
     do fcx.with_region_lb(blk.node.id) {
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index 05290d176ae..02045e3a237 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -1,9 +1,12 @@
 /* Code to handle method lookups (which can be quite complex) */
 
+import coherence::get_base_type_def_id;
+import middle::resolve3::Impl;
+import middle::typeck::infer::methods; // next_ty_vars
 import syntax::ast::def_id;
 import syntax::ast_map;
+import syntax::ast_map::node_id_to_str;
 import syntax::ast_util::new_def_hash;
-import middle::typeck::infer::methods; // next_ty_vars
 import dvec::{dvec, extensions};
 
 type candidate = {
@@ -55,11 +58,34 @@ class lookup {
 
     // Entrypoint:
     fn method() -> option<method_map_entry> {
-        #debug["method lookup(m_name=%s, self_ty=%s)",
-               *self.m_name, self.fcx.infcx.ty_to_str(self.self_ty)];
+        #debug["method lookup(m_name=%s, self_ty=%s, %?)",
+               *self.m_name, self.fcx.infcx.ty_to_str(self.self_ty),
+               ty::get(self.self_ty).struct];
+
+        // Determine if there are any inherent methods we can call.
+        let optional_inherent_methods;
+        alt get_base_type_def_id(self.fcx.infcx,
+                                 self.self_expr.span,
+                                 self.self_ty) {
+            none {
+                optional_inherent_methods = none;
+            }
+            some(base_type_def_id) {
+                #debug("(checking method) found base type");
+                optional_inherent_methods =
+                    self.fcx.ccx.coherence_info.inherent_methods.find
+                        (base_type_def_id);
+
+                if optional_inherent_methods.is_none() {
+                    #debug("(checking method) ... no inherent methods found");
+                } else {
+                    #debug("(checking method) ... inherent methods found");
+                }
+            }
+        }
 
         loop {
-            // First, see whether this is an interface-bounded parameter
+            // First, see whether this is an interface-bounded parameter.
             alt ty::get(self.self_ty).struct {
               ty::ty_param(n, did) {
                 self.add_candidates_from_param(n, did);
@@ -83,12 +109,20 @@ class lookup {
             // would require doing an implicit borrow of the lhs.
             self.add_candidates_from_scope(false);
 
+            // Look for inherent methods.
+            self.add_inherent_and_extension_candidates
+                (optional_inherent_methods, false);
+
             // if we found anything, stop before trying borrows
             if self.candidates.len() > 0u { break; }
 
             // now look for impls in scope that might require a borrow
             self.add_candidates_from_scope(true);
 
+            // Again, look for inherent methods.
+            self.add_inherent_and_extension_candidates
+                (optional_inherent_methods, true);
+
             // if we found anything, stop before attempting auto-deref.
             if self.candidates.len() > 0u { break; }
 
@@ -296,6 +330,14 @@ class lookup {
     }
 
     fn add_candidates_from_scope(use_assignability: bool) {
+        // If we're using coherence and this is one of the method invocation
+        // forms it supports, don't use this method; it'll result in lots of
+        // multiple-methods-in-scope errors.
+
+        if self.fcx.ccx.trait_map.contains_key(self.expr.id) {
+            ret;
+        }
+
         let impls_vecs = self.fcx.ccx.impl_map.get(self.expr.id);
         let mut added_any = false;
 
@@ -303,43 +345,8 @@ class lookup {
 
         for list::each(impls_vecs) |impls| {
             for vec::each(*impls) |im| {
-                // Check whether this impl has a method with the right name.
-                for im.methods.find(|m| m.ident == self.m_name).each |m| {
-
-                    // determine the `self` of the impl with fresh
-                    // variables for each parameter:
-                    let {substs: impl_substs, ty: impl_ty} =
-                        impl_self_ty(self.fcx, im.did);
-
-                    // Depending on our argument, we find potential
-                    // matches either by checking subtypability or
-                    // type assignability. Collect the matches.
-                    let matches = if use_assignability {
-                        self.fcx.can_mk_assignty(
-                            self.self_expr, self.borrow_lb,
-                            self.self_ty, impl_ty)
-                    } else {
-                        self.fcx.can_mk_subty(self.self_ty, impl_ty)
-                    };
-                    #debug["matches = %?", matches];
-                    alt matches {
-                      result::err(_) { /* keep looking */ }
-                      result::ok(_) {
-                        if !self.candidate_impls.contains_key(im.did) {
-                            let fty = self.ty_from_did(m.did);
-                            self.candidates.push(
-                                {self_ty: self.self_ty,
-                                 self_substs: impl_substs,
-                                 rcvr_ty: impl_ty,
-                                 n_tps_m: m.n_tps,
-                                 fty: fty,
-                                 entry: {derefs: self.derefs,
-                                         origin: method_static(m.did)}});
-                            self.candidate_impls.insert(im.did, ());
-                            added_any = true;
-                        }
-                      }
-                    }
+                if self.add_candidates_from_impl(im, use_assignability) {
+                    added_any = true;
                 }
             }
 
@@ -349,6 +356,53 @@ class lookup {
         }
     }
 
+    // Returns true if any were added and false otherwise.
+    fn add_candidates_from_impl(im: @resolve3::Impl,
+                                use_assignability: bool) -> bool {
+
+        let mut added_any = false;
+
+        // Check whether this impl has a method with the right name.
+        for im.methods.find(|m| m.ident == self.m_name).each |m| {
+
+            // determine the `self` of the impl with fresh
+            // variables for each parameter:
+            let {substs: impl_substs, ty: impl_ty} =
+                impl_self_ty(self.fcx, im.did);
+
+            // Depending on our argument, we find potential
+            // matches either by checking subtypability or
+            // type assignability. Collect the matches.
+            let matches = if use_assignability {
+                self.fcx.can_mk_assignty(self.self_expr, self.borrow_lb,
+                                         self.self_ty, impl_ty)
+            } else {
+                self.fcx.can_mk_subty(self.self_ty, impl_ty)
+            };
+            #debug["matches = %?", matches];
+            alt matches {
+              result::err(_) { /* keep looking */ }
+              result::ok(_) {
+                if !self.candidate_impls.contains_key(im.did) {
+                    let fty = self.ty_from_did(m.did);
+                    self.candidates.push(
+                        {self_ty: self.self_ty,
+                         self_substs: impl_substs,
+                         rcvr_ty: impl_ty,
+                         n_tps_m: m.n_tps,
+                         fty: fty,
+                         entry: {derefs: self.derefs,
+                                 origin: method_static(m.did)}});
+                    self.candidate_impls.insert(im.did, ());
+                    added_any = true;
+                }
+              }
+            }
+        }
+
+        ret added_any;
+    }
+
     fn add_candidates_from_m(self_substs: ty::substs,
                              m: ty::method,
                              origin: method_origin) {
@@ -367,6 +421,58 @@ class lookup {
              entry: {derefs: self.derefs, origin: origin}});
     }
 
+    fn add_inherent_and_extension_candidates(optional_inherent_methods:
+                                                option<@dvec<@Impl>>,
+                                             use_assignability: bool) {
+
+        // Add inherent methods.
+        alt optional_inherent_methods {
+            none {
+                // Continue.
+            }
+            some(inherent_methods) {
+                #debug("(adding inherent and extension candidates) adding \
+                        inherent candidates");
+                for inherent_methods.each |implementation| {
+                    #debug("(adding inherent and extension candidates) \
+                            adding candidates from impl: %s",
+                           node_id_to_str(self.tcx().items,
+                                          implementation.did.node));
+                    self.add_candidates_from_impl(implementation,
+                                                  use_assignability);
+                }
+            }
+        }
+
+        // Add trait methods.
+        alt self.fcx.ccx.trait_map.find(self.expr.id) {
+            none {
+                // XXX: This particular operation is not yet trait-ified;
+                // leave it alone for now.
+            }
+            some(trait_ids) {
+                for (*trait_ids).each |trait_id| {
+                    #debug("(adding inherent and extension candidates) \
+                            trying trait: %s",
+                           node_id_to_str(self.tcx().items, trait_id.node));
+
+                    let coherence_info = self.fcx.ccx.coherence_info;
+                    alt coherence_info.extension_methods.find(trait_id) {
+                        none {
+                            // Do nothing.
+                        }
+                        some(extension_methods) {
+                            for extension_methods.each |implementation| {
+                                self.add_candidates_from_impl
+                                    (implementation, use_assignability);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     fn write_mty_from_candidate(cand: candidate) -> method_map_entry {
         let tcx = self.fcx.ccx.tcx;
 
diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs
index 593b7d2a2e1..19b4450bb62 100644
--- a/src/rustc/middle/typeck/coherence.rs
+++ b/src/rustc/middle/typeck/coherence.rs
@@ -4,40 +4,121 @@
 // has at most one implementation for each type. Then we build a mapping from
 // each trait in the system to its implementations.
 
-import middle::ty::{get, t, ty_box, ty_uniq, ty_ptr, ty_rptr, ty_enum};
+import metadata::csearch::{each_path, get_impl_trait, get_impls_for_mod};
+import metadata::cstore::{cstore, iter_crate_data};
+import metadata::decoder::{dl_def, dl_field, dl_impl};
+import middle::resolve3::Impl;
+import middle::ty::{get, lookup_item_type, subst, t, ty_box};
+import middle::ty::{ty_uniq, ty_ptr, ty_rptr, ty_enum};
 import middle::ty::{ty_class, ty_nil, ty_bot, ty_bool, ty_int, ty_uint};
 import middle::ty::{ty_float, ty_estr, ty_evec, ty_rec};
 import middle::ty::{ty_fn, ty_trait, ty_tup, ty_var, ty_var_integral};
 import middle::ty::{ty_param, ty_self, ty_type, ty_opaque_box};
-import middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec, new_ty_hash};
-import middle::ty::{subst};
-import middle::typeck::infer::{infer_ctxt, mk_subty, new_infer_ctxt};
-import syntax::ast::{crate, def_id, item, item_class, item_const, item_enum};
-import syntax::ast::{item_fn, item_foreign_mod, item_impl, item_mac};
-import syntax::ast::{item_mod, item_trait, item_ty, local_crate, method};
-import syntax::ast::{node_id, trait_ref};
-import syntax::ast_util::{def_id_of_def, new_def_hash};
+import middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec, type_is_var};
+import middle::typeck::infer::{infer_ctxt, mk_subty};
+import middle::typeck::infer::{new_infer_ctxt, resolve_ivar, resolve_type};
+import syntax::ast::{crate, def_id, def_mod, item, item_class, item_const};
+import syntax::ast::{item_enum, item_fn, item_foreign_mod, item_impl};
+import syntax::ast::{item_mac, item_mod, item_trait, item_ty, local_crate};
+import syntax::ast::{method, node_id, region_param, rp_none, rp_self};
+import syntax::ast::{trait_ref};
+import syntax::ast_map::node_item;
+import syntax::ast_util::{def_id_of_def, dummy_sp, new_def_hash};
+import syntax::codemap::span;
 import syntax::visit::{default_simple_visitor, default_visitor};
 import syntax::visit::{mk_simple_visitor, mk_vt, visit_crate, visit_item};
 import syntax::visit::{visit_mod};
 import util::ppaux::ty_to_str;
 
 import dvec::{dvec, extensions};
-import result::{extensions};
+import result::{extensions, ok};
 import std::map::{hashmap, int_hash};
 import uint::range;
+import vec::{len, push};
+
+fn get_base_type(inference_context: infer_ctxt, span: span, original_type: t)
+              -> option<t> {
+
+    let resolved_type;
+    alt resolve_type(inference_context,
+                     original_type,
+                     resolve_ivar) {
+        ok(resulting_type) if !type_is_var(resulting_type) {
+            resolved_type = resulting_type;
+        }
+        _ {
+            inference_context.tcx.sess.span_fatal(span,
+                                                  ~"the type of this value \
+                                                    must be known in order \
+                                                    to determine the base \
+                                                    type");
+        }
+    }
+
+    alt get(resolved_type).struct {
+        ty_box(base_mutability_and_type) |
+        ty_uniq(base_mutability_and_type) |
+        ty_ptr(base_mutability_and_type) |
+        ty_rptr(_, base_mutability_and_type) {
+            #debug("(getting base type) recurring");
+            get_base_type(inference_context, span,
+                          base_mutability_and_type.ty)
+        }
+
+        ty_enum(*) | ty_trait(*) | ty_class(*) {
+            #debug("(getting base type) found base type");
+            some(resolved_type)
+        }
+
+        ty_nil | ty_bot | ty_bool | ty_int(*) | ty_uint(*) | ty_float(*) |
+        ty_estr(*) | ty_evec(*) | ty_rec(*) |
+        ty_fn(*) | ty_tup(*) | ty_var(*) | ty_var_integral(*) |
+        ty_param(*) | ty_self | ty_type | ty_opaque_box |
+        ty_opaque_closure_ptr(*) | ty_unboxed_vec(*) {
+            #debug("(getting base type) no base type; found %?",
+                   get(original_type).struct);
+            none
+        }
+    }
+}
+
+// Returns the def ID of the base type, if there is one.
+fn get_base_type_def_id(inference_context: infer_ctxt,
+                        span: span,
+                        original_type: t)
+                     -> option<def_id> {
+
+    alt get_base_type(inference_context, span, original_type) {
+        none {
+            ret none;
+        }
+        some(base_type) {
+            alt get(base_type).struct {
+                ty_enum(def_id, _) |
+                ty_class(def_id, _) |
+                ty_trait(def_id, _) {
+                    ret some(def_id);
+                }
+                _ {
+                    fail ~"get_base_type() returned a type that wasn't an \
+                           enum, class, or trait";
+                }
+            }
+        }
+    }
+}
 
 class CoherenceInfo {
     // Contains implementations of methods that are inherent to a type.
     // Methods in these implementations don't need to be exported.
-    let inherent_methods: hashmap<t,@dvec<@item>>;
+    let inherent_methods: hashmap<def_id,@dvec<@Impl>>;
 
     // Contains implementations of methods associated with a trait. For these,
     // the associated trait must be imported at the call site.
-    let extension_methods: hashmap<def_id,@dvec<@item>>;
+    let extension_methods: hashmap<def_id,@dvec<@Impl>>;
 
     new() {
-        self.inherent_methods = new_ty_hash();
+        self.inherent_methods = new_def_hash();
         self.extension_methods = new_def_hash();
     }
 }
@@ -45,11 +126,10 @@ class CoherenceInfo {
 class CoherenceChecker {
     let crate_context: @crate_ctxt;
     let inference_context: infer_ctxt;
-    let info: @CoherenceInfo;
 
     // A mapping from implementations to the corresponding base type
     // definition ID.
-    let base_type_def_ids: hashmap<node_id,def_id>;
+    let base_type_def_ids: hashmap<def_id,def_id>;
 
     // A set of implementations in privileged scopes; i.e. those
     // implementations that are defined in the same scope as their base types.
@@ -62,9 +142,8 @@ class CoherenceChecker {
     new(crate_context: @crate_ctxt) {
         self.crate_context = crate_context;
         self.inference_context = new_infer_ctxt(crate_context.tcx);
-        self.info = @CoherenceInfo();
 
-        self.base_type_def_ids = int_hash();
+        self.base_type_def_ids = new_def_hash();
         self.privileged_implementations = int_hash();
         self.privileged_types = new_def_hash();
     }
@@ -88,12 +167,20 @@ class CoherenceChecker {
         }));
 
         // Check trait coherence.
-        for self.info.extension_methods.each |def_id, items| {
+        for self.crate_context.coherence_info.extension_methods.each
+                |def_id, items| {
+
             self.check_implementation_coherence(def_id, items);
         }
 
         // Check whether traits with base types are in privileged scopes.
         self.check_privileged_scopes(crate);
+
+        // Bring in external crates. It's fine for this to happen after the
+        // coherence checks, because we ensure by construction that no errors
+        // can happen at link time.
+
+        self.add_external_crates();
     }
 
     fn check_implementation(item: @item,
@@ -102,111 +189,89 @@ class CoherenceChecker {
         let self_type = self.crate_context.tcx.tcache.get(local_def(item.id));
         alt optional_associated_trait {
             none {
-                alt self.get_base_type(self_type.ty) {
+                alt get_base_type_def_id(self.inference_context,
+                                         item.span,
+                                         self_type.ty) {
                     none {
                         let session = self.crate_context.tcx.sess;
-                        session.span_warn(item.span,
-                                          ~"no base type found for inherent \
-                                           implementation; implement a trait \
-                                           instead");
+                        session.span_err(item.span,
+                                         ~"no base type found for inherent \
+                                           implementation; implement a \
+                                           trait instead");
                     }
-                    some(base_type) {
-                        let implementation_list;
-                        alt self.info.inherent_methods.find(base_type) {
-                            none {
-                                implementation_list = @dvec();
-                            }
-                            some(existing_implementation_list) {
-                                implementation_list =
-                                    existing_implementation_list;
-                            }
-                        }
-
-                        implementation_list.push(item);
+                    some(_) {
+                        // Nothing to do.
                     }
                 }
             }
             some(associated_trait) {
-                let def =
-                  self.crate_context.tcx.def_map.get(associated_trait.ref_id);
-                let def_id = def_id_of_def(def);
-
-                let implementation_list;
-                alt self.info.extension_methods.find(def_id) {
-                    none {
-                        implementation_list = @dvec();
-                    }
-                    some(existing_implementation_list) {
-                        implementation_list = existing_implementation_list;
-                    }
-                }
-
-                implementation_list.push(item);
+                let def = self.crate_context.tcx.def_map.get
+                    (associated_trait.ref_id);
+                let implementation = self.create_impl_from_item(item);
+                self.add_trait_method(def_id_of_def(def), implementation);
             }
         }
 
         // Add the implementation to the mapping from implementation to base
         // type def ID, if there is a base type for this implementation.
-        alt self.get_base_type_def_id(self_type.ty) {
+        alt get_base_type_def_id(self.inference_context,
+                                 item.span,
+                                 self_type.ty) {
             none {
                 // Nothing to do.
             }
             some(base_type_def_id) {
-                self.base_type_def_ids.insert(item.id, base_type_def_id);
+                let implementation = self.create_impl_from_item(item);
+                self.add_inherent_method(base_type_def_id, implementation);
+
+                self.base_type_def_ids.insert(local_def(item.id),
+                                              base_type_def_id);
             }
         }
     }
 
-    fn get_base_type(original_type: t) -> option<t> {
-        alt get(original_type).struct {
-            ty_box(base_mutability_and_type) |
-            ty_uniq(base_mutability_and_type) |
-            ty_ptr(base_mutability_and_type) |
-            ty_rptr(_, base_mutability_and_type) {
-                self.get_base_type(base_mutability_and_type.ty)
-            }
+    fn add_inherent_method(base_def_id: def_id, implementation: @Impl) {
+        let implementation_list;
+        alt self.crate_context.coherence_info.inherent_methods
+            .find(base_def_id) {
 
-            ty_enum(*) | ty_trait(*) | ty_class(*) {
-                some(original_type)
+            none {
+                implementation_list = @dvec();
+                self.crate_context.coherence_info.inherent_methods
+                    .insert(base_def_id, implementation_list);
             }
-
-            ty_nil | ty_bot | ty_bool | ty_int(*) | ty_uint(*) | ty_float(*) |
-            ty_estr(*) | ty_evec(*) | ty_rec(*) |
-            ty_fn(*) | ty_tup(*) | ty_var(*) | ty_var_integral(*) |
-            ty_param(*) | ty_self | ty_type | ty_opaque_box |
-            ty_opaque_closure_ptr(*) | ty_unboxed_vec(*) {
-                none
+            some(existing_implementation_list) {
+                implementation_list = existing_implementation_list;
             }
         }
+
+        implementation_list.push(implementation);
     }
 
-    // Returns the def ID of the base type.
-    fn get_base_type_def_id(original_type: t) -> option<def_id> {
-        alt self.get_base_type(original_type) {
+    fn add_trait_method(trait_id: def_id, implementation: @Impl) {
+        let implementation_list;
+        alt self.crate_context.coherence_info.extension_methods
+                .find(trait_id) {
+
             none {
-                ret none;
+                implementation_list = @dvec();
+                self.crate_context.coherence_info.extension_methods
+                    .insert(trait_id, implementation_list);
             }
-            some(base_type) {
-                alt get(base_type).struct {
-                    ty_enum(def_id, _) |
-                    ty_class(def_id, _) |
-                    ty_trait(def_id, _) {
-                        ret some(def_id);
-                    }
-                    _ {
-                        fail ~"get_base_type() returned a type that \
-                               wasn't an enum, class, or trait";
-                    }
-                }
+            some(existing_implementation_list) {
+                implementation_list = existing_implementation_list;
             }
         }
+
+        implementation_list.push(implementation);
     }
 
     fn check_implementation_coherence(_trait_def_id: def_id,
-                                      implementations: @dvec<@item>) {
+                                      implementations: @dvec<@Impl>) {
 
         // Unify pairs of polytypes.
-        for implementations.eachi |i, implementation_a| {
+        for range(0, implementations.len()) |i| {
+            let implementation_a = implementations.get_elt(i);
             let polytype_a =
                 self.get_self_type_for_implementation(implementation_a);
             for range(i + 1, implementations.len()) |j| {
@@ -216,12 +281,12 @@ class CoherenceChecker {
 
                 if self.polytypes_unify(polytype_a, polytype_b) {
                     let session = self.crate_context.tcx.sess;
-                    session.span_err(implementation_b.span,
+                    session.span_err(self.span_of_impl(implementation_b),
                                      ~"conflicting implementations for a \
-                                      trait");
-                    session.span_note(
-                        implementation_a.span,
-                        ~"note conflicting implementation here");
+                                       trait");
+                    session.span_note(self.span_of_impl(implementation_a),
+                                      ~"note conflicting implementation \
+                                        here");
                 }
             }
         }
@@ -241,7 +306,7 @@ class CoherenceChecker {
     // type variables.
     fn universally_quantify_polytype(polytype: ty_param_bounds_and_ty) -> t {
         let self_region =
-            if polytype.rp {none}
+            if !polytype.rp {none}
             else {some(self.inference_context.next_region_var_nb())};
 
         let bounds_count = polytype.bounds.len();
@@ -257,25 +322,22 @@ class CoherenceChecker {
         ret subst(self.crate_context.tcx, substitutions, polytype.ty);
     }
 
-    fn get_self_type_for_implementation(implementation: @item)
+    fn get_self_type_for_implementation(implementation: @Impl)
                                      -> ty_param_bounds_and_ty {
 
-        alt implementation.node {
-            item_impl(*) {
-                let def = local_def(implementation.id);
-                ret self.crate_context.tcx.tcache.get(def);
-            }
-            _ {
-                self.crate_context.tcx.sess.span_bug(
-                    implementation.span,
-                    ~"not an implementation");
-            }
-        }
+        ret self.crate_context.tcx.tcache.get(implementation.did);
     }
 
     // Privileged scope checking
 
     fn check_privileged_scopes(crate: @crate) {
+        // Gather up all privileged types.
+        let privileged_types =
+            self.gather_privileged_types(crate.node.module.items);
+        for privileged_types.each |privileged_type| {
+            self.privileged_types.insert(privileged_type, ());
+        }
+
         visit_crate(*crate, (), mk_vt(@{
             visit_item: |item, _context, visitor| {
                 alt item.node {
@@ -301,7 +363,7 @@ class CoherenceChecker {
                         }
                     }
                     item_impl(_, optional_trait_ref, _, _) {
-                        alt self.base_type_def_ids.find(item.id) {
+                        alt self.base_type_def_ids.find(local_def(item.id)) {
                             none {
                                 // Nothing to do.
                             }
@@ -329,19 +391,18 @@ class CoherenceChecker {
 
                                             let session =
                                                 self.crate_context.tcx.sess;
-                                            session.span_warn(item.span,
-                                                              ~"cannot \
-                                                               implement \
-                                                               inherent \
-                                                               methods for a \
-                                                               type outside \
-                                                               the scope the \
-                                                               type was \
-                                                               defined in; \
-                                                               define and \
-                                                               implement a \
-                                                               trait \
-                                                               instead");
+                                            session.span_err(item.span,
+                                                             ~"cannot \
+                                                              implement \
+                                                              inherent \
+                                                              methods for a \
+                                                              type outside \
+                                                              the scope the \
+                                                              type was \
+                                                              defined in; \
+                                                              define and \
+                                                              implement a \
+                                                              trait instead");
                                         }
                                         some(trait_ref) {
                                             // This is OK if and only if the
@@ -357,13 +418,13 @@ class CoherenceChecker {
                                             if trait_id.crate != local_crate {
                                                 let session = self
                                                     .crate_context.tcx.sess;
-                                                session.span_warn(item.span,
-                                                                  ~"cannot \
+                                                session.span_err(item.span,
+                                                                 ~"cannot \
                                                                    provide \
                                                                    an \
                                                                    extension \
-                                                                   implement\
-                                                                      ation \
+                                                                   implementa\
+                                                                      tion \
                                                                    for a \
                                                                    trait not \
                                                                    defined \
@@ -405,6 +466,164 @@ class CoherenceChecker {
 
         ret results;
     }
+
+    // Converts an implementation in the AST to an Impl structure.
+    fn create_impl_from_item(item: @item) -> @Impl {
+        alt item.node {
+            item_impl(ty_params, _, _, ast_methods) {
+                let mut methods = ~[];
+                for ast_methods.each |ast_method| {
+                    push(methods, @{
+                        did: local_def(ast_method.id),
+                        n_tps: ast_method.tps.len(),
+                        ident: ast_method.ident
+                    });
+                }
+
+                ret @{
+                    did: local_def(item.id),
+                    ident: item.ident,
+                    methods: methods
+                };
+            }
+            _ {
+                self.crate_context.tcx.sess.span_bug(item.span,
+                                                     ~"can't convert a \
+                                                       non-impl to an impl");
+            }
+        }
+    }
+
+    fn span_of_impl(implementation: @Impl) -> span {
+        assert implementation.did.crate == local_crate;
+        alt self.crate_context.tcx.items.find(implementation.did.node) {
+            some(node_item(item, _)) {
+                ret item.span;
+            }
+            _ {
+                self.crate_context.tcx.sess.bug(~"span_of_impl() called on \
+                                                  something that wasn't an \
+                                                  impl!");
+            }
+        }
+    }
+
+    // External crate handling
+
+    fn add_impls_for_module(impls_seen: hashmap<def_id,()>,
+                            crate_store: cstore,
+                            module_def_id: def_id) {
+
+        let implementations = get_impls_for_mod(crate_store,
+                                                module_def_id,
+                                                none);
+        for (*implementations).each |implementation| {
+            // Make sure we don't visit the same implementation
+            // multiple times.
+            alt impls_seen.find(implementation.did) {
+                none {
+                    // Good. Continue.
+                    impls_seen.insert(implementation.did, ());
+                }
+                some(_) {
+                    // Skip this one.
+                    again;
+                }
+            }
+
+            let self_type = lookup_item_type(self.crate_context.tcx,
+                                             implementation.did);
+            let optional_trait =
+                get_impl_trait(self.crate_context.tcx,
+                               implementation.did);
+            alt optional_trait {
+                none {
+                    // This is an inherent method. There should be
+                    // no problems here, but perform a sanity check
+                    // anyway.
+
+                    alt get_base_type_def_id(self.inference_context,
+                                             dummy_sp(),
+                                             self_type.ty) {
+                        none {
+                            let session = self.crate_context.tcx.sess;
+                            session.bug(#fmt("no base type for \
+                                              external impl with no \
+                                              trait: %s (type %s)!",
+                                             *implementation.ident,
+                                             ty_to_str
+                                             (self.crate_context.tcx,
+                                              self_type.ty)));
+                        }
+                        some(_) {
+                            // Nothing to do.
+                        }
+                    }
+                }
+
+                some(trait_type) {
+                    alt get(trait_type).struct {
+                        ty_trait(trait_id, _) {
+                            self.add_trait_method(trait_id,
+                                                  implementation);
+                        }
+                        _ {
+                            self.crate_context.tcx.sess
+                                .bug(~"trait type returned is not a \
+                                       trait");
+                        }
+                    }
+                }
+            }
+
+            // Add the implementation to the mapping from
+            // implementation to base type def ID, if there is a base
+            // type for this implementation.
+
+            alt get_base_type_def_id(self.inference_context,
+                                     dummy_sp(),
+                                     self_type.ty) {
+                none {
+                    // Nothing to do.
+                }
+                some(base_type_def_id) {
+                    self.add_inherent_method(base_type_def_id,
+                                             implementation);
+
+                    self.base_type_def_ids.insert(implementation.did,
+                                                  base_type_def_id);
+                }
+            }
+        }
+    }
+
+    fn add_external_crates() {
+        let impls_seen = new_def_hash();
+
+        let crate_store = self.crate_context.tcx.sess.cstore;
+        do iter_crate_data(crate_store) |crate_number, _crate_metadata| {
+            self.add_impls_for_module(impls_seen,
+                                      crate_store,
+                                      { crate: crate_number, node: 0 });
+
+            for each_path(crate_store, crate_number) |path_entry| {
+                let module_def_id;
+                alt path_entry.def_like {
+                    dl_def(def_mod(def_id)) {
+                        module_def_id = def_id;
+                    }
+                    dl_def(_) | dl_impl(_) | dl_field {
+                        // Skip this.
+                        again;
+                    }
+                }
+
+                self.add_impls_for_module(impls_seen,
+                                          crate_store,
+                                          module_def_id);
+            }
+        }
+    }
 }
 
 fn check_coherence(crate_context: @crate_ctxt, crate: @crate) {
diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs
index 7f0294f8ba8..9334456b44c 100644
--- a/src/rustc/middle/typeck/infer.rs
+++ b/src/rustc/middle/typeck/infer.rs
@@ -437,14 +437,24 @@ fn resolve_borrowings(cx: infer_ctxt) {
     }
 }
 
-impl methods for ures {
+trait then {
+    fn then<T:copy>(f: fn() -> result<T,ty::type_err>)
+        -> result<T,ty::type_err>;
+}
+
+impl methods of then for ures {
     fn then<T:copy>(f: fn() -> result<T,ty::type_err>)
         -> result<T,ty::type_err> {
         self.chain(|_i| f())
     }
 }
 
-impl methods<T:copy> for cres<T> {
+trait cres_helpers<T> {
+    fn to_ures() -> ures;
+    fn compare(t: T, f: fn() -> ty::type_err) -> cres<T>;
+}
+
+impl methods<T:copy> of cres_helpers<T> for cres<T> {
     fn to_ures() -> ures {
         alt self {
           ok(_v) { ok(()) }
@@ -1097,19 +1107,22 @@ const force_rvar: uint          = 0b00100000;
 const force_ivar: uint          = 0b01000000;
 const force_all: uint           = 0b01110000;
 
-type resolve_state = @{
+type resolve_state_ = {
     infcx: infer_ctxt,
     modes: uint,
     mut err: option<fixup_err>,
     mut v_seen: ~[tv_vid]
 };
 
-fn resolver(infcx: infer_ctxt, modes: uint)
-    -> resolve_state {
-    @{infcx: infcx,
-      modes: modes,
-      mut err: none,
-      mut v_seen: ~[]}
+enum resolve_state {
+    resolve_state_(@resolve_state_)
+}
+
+fn resolver(infcx: infer_ctxt, modes: uint) -> resolve_state {
+    resolve_state_(@{infcx: infcx,
+                     modes: modes,
+                     mut err: none,
+                     mut v_seen: ~[]})
 }
 
 impl methods for resolve_state {
diff --git a/src/rustdoc/attr_pass.rs b/src/rustdoc/attr_pass.rs
index 4a6944ae42d..8214e8ffc98 100644
--- a/src/rustdoc/attr_pass.rs
+++ b/src/rustdoc/attr_pass.rs
@@ -6,6 +6,7 @@
      of the natural-language documentation for a crate."
 )];
 
+import doc::item_utils;
 import syntax::ast;
 import syntax::ast_map;
 import std::map::hashmap;
@@ -48,13 +49,13 @@ fn fold_crate(
     };
 
     {
-        topmod: {
+        topmod: doc::moddoc_({
             item: {
                 name: option::get_default(attrs.name, doc.topmod.name())
                 with doc.topmod.item
             }
-            with doc.topmod
-        }
+            with *doc.topmod
+        })
     }
 }
 
diff --git a/src/rustdoc/desc_to_brief_pass.rs b/src/rustdoc/desc_to_brief_pass.rs
index 15401bbf160..92078bb7d9a 100644
--- a/src/rustdoc/desc_to_brief_pass.rs
+++ b/src/rustdoc/desc_to_brief_pass.rs
@@ -5,6 +5,8 @@
  * is interpreted as the brief description.
  */
 
+import doc::item_utils;
+
 export mk_pass;
 
 fn mk_pass() -> pass {
diff --git a/src/rustdoc/doc.rs b/src/rustdoc/doc.rs
index d6b78095a15..efbd9c7cd60 100644
--- a/src/rustdoc/doc.rs
+++ b/src/rustdoc/doc.rs
@@ -2,10 +2,14 @@
 
 type ast_id = int;
 
-type doc = {
+type doc_ = {
     pages: ~[page]
 };
 
+enum doc {
+    doc_(doc_)
+}
+
 enum page {
     cratepage(cratedoc),
     itempage(itemtag)
@@ -59,12 +63,16 @@ type simpleitemdoc = {
     sig: option<~str>
 };
 
-type moddoc = {
+type moddoc_ = {
     item: itemdoc,
     items: ~[itemtag],
     index: option<index>
 };
 
+enum moddoc {
+    moddoc_(moddoc_)
+}
+
 type nmoddoc = {
     item: itemdoc,
     fns: ~[fndoc],
@@ -221,7 +229,18 @@ impl util for moddoc {
     }
 }
 
-impl util for ~[page] {
+trait page_utils {
+    fn mods() -> ~[moddoc];
+    fn nmods() -> ~[nmoddoc];
+    fn fns() -> ~[fndoc];
+    fn consts() -> ~[constdoc];
+    fn enums() -> ~[enumdoc];
+    fn traits() -> ~[traitdoc];
+    fn impls() -> ~[impldoc];
+    fn types() -> ~[tydoc];
+}
+
+impl util of page_utils for ~[page] {
 
     fn mods() -> ~[moddoc] {
         do vec::filter_map(self) |page| {
@@ -339,7 +358,16 @@ impl of item for impldoc {
     fn item() -> itemdoc { self.item }
 }
 
-impl util<A:item> for A {
+trait item_utils {
+    fn id() -> ast_id;
+    fn name() -> ~str;
+    fn path() -> ~[~str];
+    fn brief() -> option<~str>;
+    fn desc() -> option<~str>;
+    fn sections() -> ~[section];
+}
+
+impl util<A:item> of item_utils for A {
     fn id() -> ast_id {
         self.item().id
     }
diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs
index 5a14bb2ecdc..343c018a312 100644
--- a/src/rustdoc/extract.rs
+++ b/src/rustdoc/extract.rs
@@ -1,6 +1,7 @@
 //! Converts the Rust AST to the rustdoc document model
 
 import syntax::ast;
+import doc::item_utils;
 
 export from_srv, extract;
 
@@ -20,13 +21,13 @@ fn extract(
     crate: @ast::crate,
     default_name: ~str
 ) -> doc::doc {
-    {
+    doc::doc_({
         pages: ~[
             doc::cratepage({
                 topmod: top_moddoc_from_crate(crate, default_name),
             })
         ]
-    }
+    })
 }
 
 fn top_moddoc_from_crate(
@@ -53,7 +54,7 @@ fn moddoc_from_mod(
     itemdoc: doc::itemdoc,
     module: ast::_mod
 ) -> doc::moddoc {
-    {
+    doc::moddoc_({
         item: itemdoc,
         items: do vec::filter_map(module.items) |item| {
             let itemdoc = mk_itemdoc(item.id, item.ident);
@@ -104,7 +105,7 @@ fn moddoc_from_mod(
             }
         },
         index: none
-    }
+    })
 }
 
 fn nmoddoc_from_mod(
diff --git a/src/rustdoc/fold.rs b/src/rustdoc/fold.rs
index d3f7df1b7e2..11b90deecbd 100644
--- a/src/rustdoc/fold.rs
+++ b/src/rustdoc/fold.rs
@@ -132,7 +132,7 @@ fn default_par_fold<T:send copy>(ctxt: T) -> fold<T> {
 }
 
 fn default_seq_fold_doc<T>(fold: fold<T>, doc: doc::doc) -> doc::doc {
-    {
+    doc::doc_({
         pages: do vec::map(doc.pages) |page| {
             alt page {
               doc::cratepage(doc) {
@@ -143,8 +143,8 @@ fn default_seq_fold_doc<T>(fold: fold<T>, doc: doc::doc) -> doc::doc {
               }
             }
         }
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn default_seq_fold_crate<T>(
@@ -167,39 +167,39 @@ fn default_any_fold_mod<T:send copy>(
     fold: fold<T>,
     doc: doc::moddoc
 ) -> doc::moddoc {
-    {
+    doc::moddoc_({
         item: fold.fold_item(fold, doc.item),
         items: par::map(doc.items, |itemtag, copy fold| {
             fold_itemtag(fold, itemtag)
         })
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn default_seq_fold_mod<T>(
     fold: fold<T>,
     doc: doc::moddoc
 ) -> doc::moddoc {
-    {
+    doc::moddoc_({
         item: fold.fold_item(fold, doc.item),
         items: vec::map(doc.items, |itemtag| {
             fold_itemtag(fold, itemtag)
         })
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn default_par_fold_mod<T:send copy>(
     fold: fold<T>,
     doc: doc::moddoc
 ) -> doc::moddoc {
-    {
+    doc::moddoc_({
         item: fold.fold_item(fold, doc.item),
         items: par::map(doc.items, |itemtag, copy fold| {
             fold_itemtag(fold, itemtag)
         })
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn default_any_fold_nmod<T:send copy>(
diff --git a/src/rustdoc/markdown_index_pass.rs b/src/rustdoc/markdown_index_pass.rs
index 296982cb893..2aa9afe03ad 100644
--- a/src/rustdoc/markdown_index_pass.rs
+++ b/src/rustdoc/markdown_index_pass.rs
@@ -1,5 +1,7 @@
 //! Build indexes as appropriate for the markdown pass
 
+import doc::item_utils;
+
 export mk_pass;
 
 fn mk_pass(config: config::config) -> pass {
@@ -31,10 +33,10 @@ fn fold_mod(
 
     let doc = fold::default_any_fold_mod(fold, doc);
 
-    {
+    doc::moddoc_({
         index: some(build_mod_index(doc, fold.ctxt))
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn fold_nmod(
diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs
index fc03c1807d8..f3962f2a30e 100644
--- a/src/rustdoc/markdown_pass.rs
+++ b/src/rustdoc/markdown_pass.rs
@@ -1,7 +1,9 @@
 //! Generate markdown from a document tree
 
+import doc::item_utils;
 import markdown_writer::writer;
 import markdown_writer::writer_util;
+import markdown_writer::writer_utils;
 import markdown_writer::writer_factory;
 
 export mk_pass;
@@ -513,20 +515,20 @@ fn should_insert_blank_line_after_fn_signature() {
 #[test]
 fn should_correctly_indent_fn_signature() {
     let doc = test::create_doc(~"fn a() { }");
-    let doc = {
+    let doc = doc::doc_({
         pages: ~[
             doc::cratepage({
-                topmod: {
+                topmod: doc::moddoc_({
                     items: ~[doc::fntag({
                         sig: some(~"line 1\nline 2")
                         with doc.cratemod().fns()[0]
                     })]
-                    with doc.cratemod()
-                }
+                    with *doc.cratemod()
+                })
                 with doc.cratedoc()
             })
         ]
-    };
+    });
     let markdown = test::write_markdown_str(doc);
     assert str::contains(markdown, ~"    line 1\n    line 2");
 }
diff --git a/src/rustdoc/markdown_writer.rs b/src/rustdoc/markdown_writer.rs
index 5ac9998d9ea..64c7ffd6ae8 100644
--- a/src/rustdoc/markdown_writer.rs
+++ b/src/rustdoc/markdown_writer.rs
@@ -1,7 +1,10 @@
+import doc::item_utils;
+
 export writeinstr;
 export writer;
 export writer_factory;
 export writer_util;
+export writer_utils;
 export make_writer_factory;
 export future_writer_factory;
 export make_filename;
@@ -14,7 +17,13 @@ enum writeinstr {
 type writer = fn~(+writeinstr);
 type writer_factory = fn~(page: doc::page) -> writer;
 
-impl writer_util for writer {
+trait writer_utils {
+    fn write_str(str: ~str);
+    fn write_line(str: ~str);
+    fn write_done();
+}
+
+impl writer_util of writer_utils for writer {
     fn write_str(str: ~str) {
         self(write(str));
     }
diff --git a/src/rustdoc/page_pass.rs b/src/rustdoc/page_pass.rs
index 972a697202e..e5e3866242d 100644
--- a/src/rustdoc/page_pass.rs
+++ b/src/rustdoc/page_pass.rs
@@ -5,6 +5,7 @@
  * individual modules, pages for the crate, indexes, etc.
  */
 
+import doc::{item_utils, page_utils};
 import syntax::ast;
 
 export mk_pass;
@@ -51,9 +52,9 @@ fn make_doc_from_pages(page_port: page_port) -> doc::doc {
             break;
         }
     }
-    {
+    doc::doc_({
         pages: pages
-    }
+    })
 }
 
 fn find_pages(doc: doc::doc, page_chan: page_chan) {
@@ -103,7 +104,7 @@ fn fold_mod(
 }
 
 fn strip_mod(doc: doc::moddoc) -> doc::moddoc {
-    {
+    doc::moddoc_({
         items: do vec::filter(doc.items) |item| {
             alt item {
               doc::modtag(_) { false }
@@ -111,8 +112,8 @@ fn strip_mod(doc: doc::moddoc) -> doc::moddoc {
               _ { true }
             }
         }
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn fold_nmod(
diff --git a/src/rustdoc/path_pass.rs b/src/rustdoc/path_pass.rs
index 45cd7287862..ffef3ac7815 100644
--- a/src/rustdoc/path_pass.rs
+++ b/src/rustdoc/path_pass.rs
@@ -1,5 +1,6 @@
 //! Records the full path to items
 
+import doc::item_utils;
 import syntax::ast;
 
 export mk_pass;
@@ -46,10 +47,10 @@ fn fold_mod(fold: fold::fold<ctxt>, doc: doc::moddoc) -> doc::moddoc {
     let doc = fold::default_any_fold_mod(fold, doc);
     if !is_topmod { vec::pop(fold.ctxt.path); }
 
-    {
+    doc::moddoc_({
         item: fold.fold_item(fold, doc.item)
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn fold_nmod(fold: fold::fold<ctxt>, doc: doc::nmoddoc) -> doc::nmoddoc {
diff --git a/src/rustdoc/prune_hidden_pass.rs b/src/rustdoc/prune_hidden_pass.rs
index f5899e29df3..dbb65f0e2d1 100644
--- a/src/rustdoc/prune_hidden_pass.rs
+++ b/src/rustdoc/prune_hidden_pass.rs
@@ -1,5 +1,6 @@
 //! Prunes things with the #[doc(hidden)] attribute
 
+import doc::item_utils;
 import std::map::hashmap;
 export mk_pass;
 
@@ -24,12 +25,12 @@ fn fold_mod(
 ) -> doc::moddoc {
     let doc = fold::default_any_fold_mod(fold, doc);
 
-    {
+    doc::moddoc_({
         items: vec::filter(doc.items, |itemtag| {
             !is_hidden(fold.ctxt, itemtag.item())
         })
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn is_hidden(srv: astsrv::srv, doc: doc::itemdoc) -> bool {
diff --git a/src/rustdoc/prune_unexported_pass.rs b/src/rustdoc/prune_unexported_pass.rs
index 00173e38850..03d8a3de127 100644
--- a/src/rustdoc/prune_unexported_pass.rs
+++ b/src/rustdoc/prune_unexported_pass.rs
@@ -1,5 +1,6 @@
 //! Prunes branches of the tree that are not exported
 
+import doc::item_utils;
 import syntax::ast;
 import syntax::ast_util;
 import syntax::ast_map;
@@ -24,10 +25,10 @@ fn run(srv: astsrv::srv, doc: doc::doc) -> doc::doc {
 
 fn fold_mod(fold: fold::fold<astsrv::srv>, doc: doc::moddoc) -> doc::moddoc {
     let doc = fold::default_any_fold_mod(fold, doc);
-    {
+    doc::moddoc_({
         items: exported_items(fold.ctxt, doc)
-        with doc
-    }
+        with *doc
+    })
 }
 
 fn exported_items(srv: astsrv::srv, doc: doc::moddoc) -> ~[doc::itemtag] {
diff --git a/src/rustdoc/reexport_pass.rs b/src/rustdoc/reexport_pass.rs
index 75f53b7ab0a..29f76d16225 100644
--- a/src/rustdoc/reexport_pass.rs
+++ b/src/rustdoc/reexport_pass.rs
@@ -1,5 +1,6 @@
 //! Finds docs for reexported items and duplicates them
 
+import doc::item_utils;
 import std::map;
 import std::map::hashmap;
 import std::list;
@@ -331,10 +332,10 @@ fn merge_reexports(
         let new_items = get_new_items(path, fold.ctxt);
         #debug("merging into %?: %?", path, new_items);
 
-        {
+        doc::moddoc_({
             items: (doc.items + new_items)
-            with doc
-        }
+            with *doc
+        })
     }
 
     fn get_new_items(path: ~[~str], path_map: path_map) -> ~[doc::itemtag] {
@@ -352,11 +353,11 @@ fn merge_reexports(
 
     fn reexport_doc(doc: doc::itemtag, name: ~str) -> doc::itemtag {
         alt doc {
-          doc::modtag(doc @ {item, _}) {
-            doc::modtag({
+          doc::modtag(doc @ doc::moddoc_({item, _})) {
+            doc::modtag(doc::moddoc_({
                 item: reexport(item, name)
-                with doc
-            })
+                with *doc
+            }))
           }
           doc::nmodtag(_) { fail }
           doc::consttag(doc @ {item, _}) {
diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs
index 952539376ef..21db670f781 100755
--- a/src/rustdoc/rustdoc.rs
+++ b/src/rustdoc/rustdoc.rs
@@ -1,4 +1,5 @@
 // Some utility interfaces
+import doc::item_utils;
 import doc::item;
 import doc::util;
 
@@ -47,39 +48,39 @@ fn test_run_passes() {
         _srv: astsrv::srv,
         doc: doc::doc
     ) -> doc::doc {
-        {
+        doc::doc_({
             pages: ~[
                 doc::cratepage({
-                    topmod: {
+                    topmod: doc::moddoc_({
                         item: {
                             name: doc.cratemod().name() + ~"two"
                             with doc.cratemod().item
                         },
                         items: ~[],
                         index: none
-                    }
+                    })
                 })
             ]
-        }
+        })
     }
     fn pass2(
         _srv: astsrv::srv,
         doc: doc::doc
     ) -> doc::doc {
-        {
+        doc::doc_({
             pages: ~[
                 doc::cratepage({
-                    topmod: {
+                    topmod: doc::moddoc_({
                         item: {
                             name: doc.cratemod().name() + ~"three"
                             with doc.cratemod().item
                         },
                         items: ~[],
                         index: none
-                    }
+                    })
                 })
             ]
-        }
+        })
     }
     let source = ~"";
     do astsrv::from_str(source) |srv| {
diff --git a/src/rustdoc/sectionalize_pass.rs b/src/rustdoc/sectionalize_pass.rs
index b7adfc17c4d..a06ace65450 100644
--- a/src/rustdoc/sectionalize_pass.rs
+++ b/src/rustdoc/sectionalize_pass.rs
@@ -1,5 +1,7 @@
 //! Breaks rustdocs into sections according to their headers
 
+import doc::item_utils;
+
 export mk_pass;
 
 fn mk_pass() -> pass {
diff --git a/src/rustdoc/sort_item_name_pass.rs b/src/rustdoc/sort_item_name_pass.rs
index daf7d97c2ea..6fe4a900699 100644
--- a/src/rustdoc/sort_item_name_pass.rs
+++ b/src/rustdoc/sort_item_name_pass.rs
@@ -1,5 +1,6 @@
 //! Sorts items by name
 
+import doc::item_utils;
 export mk_pass;
 
 fn mk_pass() -> pass {
diff --git a/src/rustdoc/sort_item_type_pass.rs b/src/rustdoc/sort_item_type_pass.rs
index bc2650e590a..43b197fb015 100644
--- a/src/rustdoc/sort_item_type_pass.rs
+++ b/src/rustdoc/sort_item_type_pass.rs
@@ -1,5 +1,7 @@
 //! Sorts items by type
 
+import doc::item_utils;
+
 export mk_pass;
 
 fn mk_pass() -> pass {
diff --git a/src/rustdoc/sort_pass.rs b/src/rustdoc/sort_pass.rs
index a95de20d1ba..5501fb937ce 100644
--- a/src/rustdoc/sort_pass.rs
+++ b/src/rustdoc/sort_pass.rs
@@ -1,5 +1,6 @@
 //! A general sorting pass
 
+import doc::item_utils;
 import std::sort;
 
 export item_lteq, mk_pass;
@@ -34,10 +35,10 @@ fn fold_mod(
     doc: doc::moddoc
 ) -> doc::moddoc {
     let doc = fold::default_any_fold_mod(fold, doc);
-    {
+    doc::moddoc_({
         items: sort::merge_sort(fold.ctxt, doc.items)
-        with doc
-    }
+        with *doc
+    })
 }
 
 #[test]
diff --git a/src/rustdoc/text_pass.rs b/src/rustdoc/text_pass.rs
index a27d1a09da6..c98b1fd7e84 100644
--- a/src/rustdoc/text_pass.rs
+++ b/src/rustdoc/text_pass.rs
@@ -1,5 +1,7 @@
 //! Generic pass for performing an operation on all descriptions
 
+import doc::item_utils;
+
 export mk_pass;
 
 fn mk_pass(name: ~str, +op: fn~(~str) -> ~str) -> pass {
diff --git a/src/rustdoc/trim_pass.rs b/src/rustdoc/trim_pass.rs
index 1a5e96dbed4..3ce36f187d7 100644
--- a/src/rustdoc/trim_pass.rs
+++ b/src/rustdoc/trim_pass.rs
@@ -5,6 +5,8 @@
  * is interpreted as the brief description.
  */
 
+import doc::item_utils;
+
 export mk_pass;
 
 fn mk_pass() -> pass {
diff --git a/src/rustdoc/tystr_pass.rs b/src/rustdoc/tystr_pass.rs
index d3c7adb51a4..b22c7e121c7 100644
--- a/src/rustdoc/tystr_pass.rs
+++ b/src/rustdoc/tystr_pass.rs
@@ -1,5 +1,6 @@
 //! Pulls type information out of the AST and attaches it to the document
 
+import doc::item_utils;
 import syntax::ast;
 import syntax::print::pprust;
 import syntax::ast_map;
diff --git a/src/test/auxiliary/ambig_impl_2_lib.rs b/src/test/auxiliary/ambig_impl_2_lib.rs
index 2ea30d4e078..bf838a9d22c 100644
--- a/src/test/auxiliary/ambig_impl_2_lib.rs
+++ b/src/test/auxiliary/ambig_impl_2_lib.rs
@@ -1 +1,4 @@
-impl methods1 for uint { fn me() -> uint { self } }
+trait me {
+    fn me() -> uint;
+}
+impl methods1 of me for uint { fn me() -> uint { self } }
diff --git a/src/test/auxiliary/cci_impl_lib.rs b/src/test/auxiliary/cci_impl_lib.rs
index a14dbc2eedd..af5fa814c6a 100644
--- a/src/test/auxiliary/cci_impl_lib.rs
+++ b/src/test/auxiliary/cci_impl_lib.rs
@@ -1,6 +1,10 @@
 #[link(name="cci_impl_lib", vers="0.0")];
 
-impl helpers for uint {
+trait uint_helpers {
+    fn to(v: uint, f: fn(uint));
+}
+
+impl helpers of uint_helpers for uint {
     #[inline]
     fn to(v: uint, f: fn(uint)) {
         let mut i = self;
@@ -9,4 +13,4 @@ impl helpers for uint {
             i += 1u;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs b/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs
index 97787cc8406..3a7f3844019 100644
--- a/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs
+++ b/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs
@@ -2,13 +2,18 @@
 
 export rust;
 
+import name_pool::add;
 import name_pool::methods;
 
 mod name_pool {
 
     type name_pool = ();
 
-    impl methods for name_pool {
+    trait add {
+        fn add(s: ~str);
+    }
+
+    impl methods of add for name_pool {
         fn add(s: ~str) {
         }
     }
@@ -16,12 +21,19 @@ mod name_pool {
 
 mod rust {
 
+    import name_pool::add;
+    export add;
     export rt;
     export methods;
+    export cx;
 
     type rt = @();
 
-    impl methods for rt {
+    trait cx {
+        fn cx();
+    }
+
+    impl methods of cx for rt {
         fn cx() {
         }
     }
diff --git a/src/test/auxiliary/issue-2414-a.rs b/src/test/auxiliary/issue-2414-a.rs
index 01cadc92246..5eb25c4f44f 100644
--- a/src/test/auxiliary/issue-2414-a.rs
+++ b/src/test/auxiliary/issue-2414-a.rs
@@ -2,4 +2,12 @@
 #[crate_type = "lib"];
 
 type t1 = uint;
-impl t2 for ~str { }
+
+trait foo {
+    fn foo();
+}
+
+impl t2 of foo for ~str {
+    fn foo() {}
+}
+
diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs
index bd3f2c615bf..3fea95383d5 100644
--- a/src/test/bench/graph500-bfs.rs
+++ b/src/test/bench/graph500-bfs.rs
@@ -7,6 +7,7 @@ An implementation of the Graph500 Breadth First Search problem in Rust.
 use std;
 import std::time;
 import std::map;
+import std::map::map;
 import std::map::hashmap;
 import std::deque;
 import std::deque::t;
diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs
index aa6377633c2..7385313d53a 100644
--- a/src/test/bench/shootout-mandelbrot.rs
+++ b/src/test/bench/shootout-mandelbrot.rs
@@ -19,7 +19,12 @@ import std::map::hashmap;
 type cmplx = {re: f64, im: f64};
 type line = {i: uint, b: ~[u8]};
 
-impl arith for cmplx {
+trait times_and_plus {
+    fn *(x: cmplx) -> cmplx;
+    fn +(x: cmplx) -> cmplx;
+}
+
+impl arith of times_and_plus for cmplx {
     fn *(x: cmplx) -> cmplx {
         {re: self.re*x.re - self.im*x.im, im: self.re*x.im + self.im*x.re}
     }
diff --git a/src/test/compile-fail/ambig_impl_1.rs b/src/test/compile-fail/ambig_impl_1.rs
deleted file mode 100644
index 51247c7e8e9..00000000000
--- a/src/test/compile-fail/ambig_impl_1.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-impl methods1 for uint { fn me() -> uint { self } } //~ NOTE candidate #1 is `methods1::me`
-impl methods2 for uint { fn me() -> uint { self } } //~ NOTE candidate #2 is `methods2::me`
-fn main() { 1u.me(); } //~ ERROR multiple applicable methods in scope
diff --git a/src/test/compile-fail/ambig_impl_2_exe.rs b/src/test/compile-fail/ambig_impl_2_exe.rs
index fe7e27dce23..fe603738440 100644
--- a/src/test/compile-fail/ambig_impl_2_exe.rs
+++ b/src/test/compile-fail/ambig_impl_2_exe.rs
@@ -2,6 +2,10 @@
 // aux-build:ambig_impl_2_lib.rs
 use ambig_impl_2_lib;
 import ambig_impl_2_lib::methods1;
-impl methods2 for uint { fn me() -> uint { self } } //~ NOTE is `methods2::me`
+import ambig_impl_2_lib::me;
+trait me {
+    fn me() -> uint;
+}
+impl methods2 of me for uint { fn me() -> uint { self } } //~ NOTE is `methods2::me`
 fn main() { 1u.me(); } //~ ERROR multiple applicable methods in scope
 //~^ NOTE is `ambig_impl_2_lib::methods1::me`
diff --git a/src/test/compile-fail/ambig_impl_unify.rs b/src/test/compile-fail/ambig_impl_unify.rs
index bb2009fc931..f6994536a99 100644
--- a/src/test/compile-fail/ambig_impl_unify.rs
+++ b/src/test/compile-fail/ambig_impl_unify.rs
@@ -1,12 +1,16 @@
-impl methods for ~[uint] {
+trait foo {
+    fn foo() -> int;
+}
+
+impl methods of foo for ~[uint] {
     fn foo() -> int {1} //~ NOTE candidate #1 is `methods::foo`
 }
 
-impl methods for ~[int] {
+impl methods of foo for ~[int] {
     fn foo() -> int {2} //~ NOTE candidate #2 is `methods::foo`
 }
 
 fn main() {
     let x = ~[];
     x.foo(); //~ ERROR multiple applicable methods in scope
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/bad-method-typaram-kind.rs b/src/test/compile-fail/bad-method-typaram-kind.rs
index 9934702fdea..18f160ce8e4 100644
--- a/src/test/compile-fail/bad-method-typaram-kind.rs
+++ b/src/test/compile-fail/bad-method-typaram-kind.rs
@@ -2,7 +2,11 @@ fn foo<T>() {
     1u.bar::<T>(); //~ ERROR: missing `copy`
 }
 
-impl methods for uint {
+trait bar {
+    fn bar<T:copy>();
+}
+
+impl methods of bar for uint {
     fn bar<T:copy>() {
     }
 }
diff --git a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
index f75b256079e..4e084ba35c3 100644
--- a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
+++ b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
@@ -1,6 +1,11 @@
 type point = { x: int, y: int };
 
-impl foo for point {
+trait add_and_times {
+    pure fn +(z: int) -> int;
+    fn *(z: int) -> int;
+}
+
+impl foo of add_and_times for point {
     pure fn +(z: int) -> int { self.x + self.y + z }
     fn *(z: int) -> int { self.x * self.y * z }
 }
diff --git a/src/test/compile-fail/borrowck-loan-rcvr.rs b/src/test/compile-fail/borrowck-loan-rcvr.rs
index 89adfc4d2f1..77cec9c869c 100644
--- a/src/test/compile-fail/borrowck-loan-rcvr.rs
+++ b/src/test/compile-fail/borrowck-loan-rcvr.rs
@@ -1,6 +1,12 @@
 type point = { x: int, y: int };
 
-impl foo for point {
+trait methods {
+    fn impurem();
+    fn blockm(f: fn());
+    pure fn purem();
+}
+
+impl foo of methods for point {
     fn impurem() {
     }
 
diff --git a/src/test/compile-fail/iface-test-2.rs b/src/test/compile-fail/iface-test-2.rs
index b2ee357ffc5..dc1b9501df0 100644
--- a/src/test/compile-fail/iface-test-2.rs
+++ b/src/test/compile-fail/iface-test-2.rs
@@ -1,11 +1,9 @@
 iface bar { fn dup() -> self; fn blah<X>(); }
 impl of bar for int { fn dup() -> int { self } fn blah<X>() {} }
 impl of bar for uint { fn dup() -> uint { self } fn blah<X>() {} }
-impl of bar for uint { fn dup() -> uint { self } fn blah<X>() {} }
 
 fn main() {
     10.dup::<int>(); //~ ERROR does not take type parameters
     10.blah::<int, int>(); //~ ERROR incorrect number of type parameters
-    10u.dup(); //~ ERROR multiple applicable methods
     (10 as bar).dup(); //~ ERROR contains a self type
 }
diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs
index 13f857a5a13..d2d8744e479 100644
--- a/src/test/compile-fail/issue-2063.rs
+++ b/src/test/compile-fail/issue-2063.rs
@@ -3,10 +3,14 @@
 // of such a type could ever be constructed.
 enum t = @t; //~ ERROR this type cannot be instantiated
 
+trait to_str_2 {
+    fn to_str() -> ~str;
+}
+
 // I use an impl here because it will cause
 // the compiler to attempt autoderef and then
 // try to resolve the method.
-impl methods for t {
+impl methods of to_str_2 for t {
     fn to_str() -> ~str { ~"t" }
 }
 
diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs
index df2138fc15a..344d151ae2b 100644
--- a/src/test/compile-fail/issue-2149.rs
+++ b/src/test/compile-fail/issue-2149.rs
@@ -1,4 +1,8 @@
-impl monad<A> for ~[A] {
+trait vec_monad<A> {
+    fn bind<B>(f: fn(A) -> ~[B]);
+}
+
+impl monad<A> of vec_monad<A> for ~[A] {
     fn bind<B>(f: fn(A) -> ~[B]) {
         let mut r = fail;
         for self.each |elt| { r += f(elt); }
@@ -8,4 +12,4 @@ impl monad<A> for ~[A] {
 }
 fn main() {
     ["hi"].bind({|x| [x] });
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/issue-2590.rs b/src/test/compile-fail/issue-2590.rs
index 5aba0e50fd6..132ce4757e0 100644
--- a/src/test/compile-fail/issue-2590.rs
+++ b/src/test/compile-fail/issue-2590.rs
@@ -4,7 +4,11 @@ type parser = {
     tokens: dvec<int>,
 };
 
-impl parser for parser {
+trait parse {
+    fn parse() -> ~[mut int];
+}
+
+impl parser of parse for parser {
     fn parse() -> ~[mut int] {
         dvec::unwrap(self.tokens) //~ ERROR illegal move from self
     }
diff --git a/src/test/compile-fail/placement-new-bad-method-type.rs b/src/test/compile-fail/placement-new-bad-method-type.rs
index 2126a6bddc6..2cbf91c8d2a 100644
--- a/src/test/compile-fail/placement-new-bad-method-type.rs
+++ b/src/test/compile-fail/placement-new-bad-method-type.rs
@@ -2,7 +2,11 @@ import libc, unsafe;
 
 enum malloc_pool = ();
 
-impl methods for malloc_pool {
+trait alloc {
+    fn alloc(sz: int, align: int) -> *();
+}
+
+impl methods of alloc for malloc_pool {
     fn alloc(sz: int, align: int) -> *() {
         fail;
     }
diff --git a/src/test/compile-fail/pure-modifies-aliased.rs b/src/test/compile-fail/pure-modifies-aliased.rs
index d63169d512f..20cb1fa6b6b 100644
--- a/src/test/compile-fail/pure-modifies-aliased.rs
+++ b/src/test/compile-fail/pure-modifies-aliased.rs
@@ -8,11 +8,15 @@ pure fn modify_in_box(sum: @mut {f: int}) {
     sum.f = 3; //~ ERROR assigning to mutable field prohibited in pure context
 }
 
-impl foo for int {
+trait modify_in_box_rec {
+    pure fn modify_in_box_rec(sum: @{mut f: int});
+}
+
+impl foo of modify_in_box_rec for int {
     pure fn modify_in_box_rec(sum: @{mut f: int}) {
         sum.f = self; //~ ERROR assigning to mutable field prohibited in pure context
     }
 }
 
 fn main() {
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/pure-overloaded-op.rs b/src/test/compile-fail/pure-overloaded-op.rs
index 3f29e385202..c07512e20f5 100644
--- a/src/test/compile-fail/pure-overloaded-op.rs
+++ b/src/test/compile-fail/pure-overloaded-op.rs
@@ -1,6 +1,13 @@
 type point = { x: int, y: int };
 
-impl foo for point {
+trait operators {
+    pure fn +(z: int) -> int;
+    fn *(z: int) -> int;
+    fn [](z: int) -> int;
+    fn unary-() -> int;
+}
+
+impl foo of operators for point {
     // expr_binary
     pure fn +(z: int) -> int { self.x + self.y + z }
     fn *(z: int) -> int { self.x * self.y * z }
diff --git a/src/test/compile-fail/regions-infer-paramd-indirect.rs b/src/test/compile-fail/regions-infer-paramd-indirect.rs
index b00ae17ddf7..9a2329f849e 100644
--- a/src/test/compile-fail/regions-infer-paramd-indirect.rs
+++ b/src/test/compile-fail/regions-infer-paramd-indirect.rs
@@ -5,7 +5,12 @@ type a = &int;
 type b = @a;
 type c = {f: @b};
 
-impl methods for c {
+trait set_f {
+    fn set_f_ok(b: @b/&self);
+    fn set_f_bad(b: @b);
+}
+
+impl methods of set_f for c {
     fn set_f_ok(b: @b/&self) {
         self.f = b;
     }
@@ -15,4 +20,4 @@ impl methods for c {
     }
 }
 
-fn main() {}
\ No newline at end of file
+fn main() {}
diff --git a/src/test/compile-fail/regions-infer-paramd-method.rs b/src/test/compile-fail/regions-infer-paramd-method.rs
index 125abb5e0f7..33c699c0c86 100644
--- a/src/test/compile-fail/regions-infer-paramd-method.rs
+++ b/src/test/compile-fail/regions-infer-paramd-method.rs
@@ -9,7 +9,11 @@ iface foo {
 
 type with_foo = {mut f: foo};
 
-impl methods for with_foo {
+trait set_foo_foo {
+    fn set_foo(f: foo);
+}
+
+impl methods of set_foo_foo for with_foo {
     fn set_foo(f: foo) {
         self.f = f; //~ ERROR mismatched types: expected `foo/&self` but found `foo/&`
     }
@@ -23,10 +27,14 @@ iface bar {
 
 type with_bar = {mut f: bar};
 
-impl methods for with_bar {
+trait set_foo_bar {
+    fn set_foo(f: bar);
+}
+
+impl methods of set_foo_bar for with_bar {
     fn set_foo(f: bar) {
         self.f = f;
     }
 }
 
-fn main() {}
\ No newline at end of file
+fn main() {}
diff --git a/src/test/run-pass/autoderef-method-newtype.rs b/src/test/run-pass/autoderef-method-newtype.rs
index 6d1d4428348..3d67a5fd1f5 100644
--- a/src/test/run-pass/autoderef-method-newtype.rs
+++ b/src/test/run-pass/autoderef-method-newtype.rs
@@ -1,4 +1,8 @@
-impl methods for uint {
+trait double {
+    fn double() -> uint;
+}
+
+impl methods of double for uint {
     fn double() -> uint { self * 2u }
 }
 
diff --git a/src/test/run-pass/autoderef-method-priority.rs b/src/test/run-pass/autoderef-method-priority.rs
index 4f9dd19abbd..23f2a5e6b49 100644
--- a/src/test/run-pass/autoderef-method-priority.rs
+++ b/src/test/run-pass/autoderef-method-priority.rs
@@ -1,8 +1,12 @@
-impl methods for uint {
+trait double {
+    fn double() -> uint;
+}
+
+impl methods of double for uint {
     fn double() -> uint { self }
 }
 
-impl methods for @uint {
+impl methods of double for @uint {
     fn double() -> uint { *self * 2u }
 }
 
diff --git a/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs b/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs
index 4c15661e8f0..45f8ffde6d8 100644
--- a/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs
+++ b/src/test/run-pass/autoderef-method-twice-but-not-thrice.rs
@@ -1,4 +1,8 @@
-impl methods for @@uint {
+trait double {
+    fn double() -> uint;
+}
+
+impl methods of double for @@uint {
     fn double() -> uint { **self * 2u }
 }
 
diff --git a/src/test/run-pass/autoderef-method-twice.rs b/src/test/run-pass/autoderef-method-twice.rs
index 3587e1d83a1..899769352d6 100644
--- a/src/test/run-pass/autoderef-method-twice.rs
+++ b/src/test/run-pass/autoderef-method-twice.rs
@@ -1,4 +1,8 @@
-impl methods for uint {
+trait double {
+    fn double() -> uint;
+}
+
+impl methods of double for uint {
     fn double() -> uint { self * 2u }
 }
 
diff --git a/src/test/run-pass/autoderef-method.rs b/src/test/run-pass/autoderef-method.rs
index 7ea03d0d7e4..5b66ce718f4 100644
--- a/src/test/run-pass/autoderef-method.rs
+++ b/src/test/run-pass/autoderef-method.rs
@@ -1,4 +1,8 @@
-impl methods for uint {
+trait double {
+    fn double() -> uint;
+}
+
+impl methods of double for uint {
     fn double() -> uint { self * 2u }
 }
 
diff --git a/src/test/run-pass/borrowck-newtype-issue-2573.rs b/src/test/run-pass/borrowck-newtype-issue-2573.rs
index 5ca39da8cb3..108613f54a2 100644
--- a/src/test/run-pass/borrowck-newtype-issue-2573.rs
+++ b/src/test/run-pass/borrowck-newtype-issue-2573.rs
@@ -2,7 +2,11 @@ enum foo = {mut bar: baz};
 
 enum baz = @{mut baz: int};
 
-impl quuux for foo {
+trait frob {
+    fn frob();
+}
+
+impl quuux of frob for foo {
     fn frob() {
         really_impure(self.bar);
     }
@@ -13,4 +17,4 @@ fn really_impure(++bar: baz) {
     bar.baz = 3;
 }
 
-fn main() {}
\ No newline at end of file
+fn main() {}
diff --git a/src/test/run-pass/cci_impl_exe.rs b/src/test/run-pass/cci_impl_exe.rs
index d69982b58de..04dd607d76e 100644
--- a/src/test/run-pass/cci_impl_exe.rs
+++ b/src/test/run-pass/cci_impl_exe.rs
@@ -3,6 +3,7 @@
 
 use cci_impl_lib;
 import cci_impl_lib::helpers;
+import cci_impl_lib::uint_helpers;
 
 fn main() {
     //let bt0 = sys::frame_address();
diff --git a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs b/src/test/run-pass/crate-method-reexport-grrrrrrr.rs
index 8d5260290b4..37da90be375 100644
--- a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs
+++ b/src/test/run-pass/crate-method-reexport-grrrrrrr.rs
@@ -9,6 +9,8 @@ use crate_method_reexport_grrrrrrr2;
 
 fn main() {
     import crate_method_reexport_grrrrrrr2::rust::methods;
+    import crate_method_reexport_grrrrrrr2::rust::add;
+    import crate_method_reexport_grrrrrrr2::rust::cx;
     let x = @();
     x.cx();
     let y = ();
diff --git a/src/test/run-pass/fixed_length_vec_glue.rs b/src/test/run-pass/fixed_length_vec_glue.rs
index 017a17684ec..64459fbe91c 100644
--- a/src/test/run-pass/fixed_length_vec_glue.rs
+++ b/src/test/run-pass/fixed_length_vec_glue.rs
@@ -1,6 +1,6 @@
 fn main() {
     let arr = [1,2,3]/3;
-    let struct = {a: 13u8, b: arr, c: 42};
-    let s = sys::log_str(struct);
+    let struc = {a: 13u8, b: arr, c: 42};
+    let s = sys::log_str(struc);
     assert(s == ~"(13, [1, 2, 3]/3, 42)");
 }
diff --git a/src/test/run-pass/impl-variance.rs b/src/test/run-pass/impl-variance.rs
index a5ea5a75de3..1a913abbbf0 100644
--- a/src/test/run-pass/impl-variance.rs
+++ b/src/test/run-pass/impl-variance.rs
@@ -1,4 +1,8 @@
-impl extensions<T> for ~[const T] {
+trait foo {
+    fn foo() -> uint;
+}
+
+impl extensions<T> of foo for ~[const T] {
     fn foo() -> uint { vec::len(self) }
 }
 
@@ -9,4 +13,4 @@ fn main() {
     assert v.foo() == 1u;
     let v = ~[mut 0];
     assert v.foo() == 1u;
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/int-conversion-coherence.rs b/src/test/run-pass/int-conversion-coherence.rs
new file mode 100644
index 00000000000..ab75dd6b4e5
--- /dev/null
+++ b/src/test/run-pass/int-conversion-coherence.rs
@@ -0,0 +1,16 @@
+// xfail-test
+//
+// Problem here is that transactions aren't implemented for integer literal
+// inference.
+
+trait plus {
+    fn plus() -> int;
+}
+
+impl foo of plus for uint { fn plus() -> int { self as int + 20 } }
+impl foo of plus for int { fn plus() -> int { self + 10 } }
+
+fn main() {
+    assert 10.plus() == 20;
+}
+
diff --git a/src/test/run-pass/method-attributes.rs b/src/test/run-pass/method-attributes.rs
index 32230dfca02..0b711682b0a 100644
--- a/src/test/run-pass/method-attributes.rs
+++ b/src/test/run-pass/method-attributes.rs
@@ -9,7 +9,7 @@ iface frobable {
 }
 
 #[int_frobable]
-impl frobable for int {
+impl frobable of frobable for int {
     #[frob_attr1]
     fn frob() {
         #[frob_attr2];
diff --git a/src/test/run-pass/module-polymorphism4-files/trait.rs b/src/test/run-pass/module-polymorphism4-files/trait.rs
index e5762d156a0..ec68d32ba95 100644
--- a/src/test/run-pass/module-polymorphism4-files/trait.rs
+++ b/src/test/run-pass/module-polymorphism4-files/trait.rs
@@ -1,4 +1,8 @@
-impl talky for T {
+trait says {
+    fn says() -> ~str;
+}
+
+impl talky of says for T {
 
     // 'animal' and 'talk' functions are implemented by the module
     // instantiating the talky trait. They are 'abstract'
diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs
index a1e52d44e6b..3b0f6c1bbdf 100644
--- a/src/test/run-pass/monad.rs
+++ b/src/test/run-pass/monad.rs
@@ -1,4 +1,8 @@
-impl monad<A> for ~[A] {
+trait vec_monad<A> {
+    fn bind<B>(f: fn(A) -> ~[B]) -> ~[B];
+}
+
+impl monad<A> of vec_monad<A> for ~[A] {
     fn bind<B>(f: fn(A) -> ~[B]) -> ~[B] {
         let mut r = ~[];
         for self.each |elt| { r += f(elt); }
@@ -6,7 +10,11 @@ impl monad<A> for ~[A] {
     }
 }
 
-impl monad<A> for option<A> {
+trait option_monad<A> {
+    fn bind<B>(f: fn(A) -> option<B>) -> option<B>;
+}
+
+impl monad<A> of option_monad<A> for option<A> {
     fn bind<B>(f: fn(A) -> option<B>) -> option<B> {
         alt self {
           some(a) { f(a) }
diff --git a/src/test/run-pass/operator-overloading-leaks.rs b/src/test/run-pass/operator-overloading-leaks.rs
index 20f6201bd6b..c3a0dcec7df 100644
--- a/src/test/run-pass/operator-overloading-leaks.rs
+++ b/src/test/run-pass/operator-overloading-leaks.rs
@@ -1,6 +1,11 @@
 // The cases commented as "Leaks" need to not leak. Issue #2581
 
-impl methods<T: copy> for ~[T] {
+trait minus_and_foo<T> {
+    fn -(x: &[T]) -> ~[T];
+    fn foo(x: &[T]) -> ~[T];
+}
+
+impl methods<T: copy> of minus_and_foo<T> for ~[T] {
     fn -(x: &[T]) -> ~[T] {
         ~[x[0], x[0], x[0]]
     }
@@ -10,19 +15,31 @@ impl methods<T: copy> for ~[T] {
     }
 }
 
-impl methods<T: copy> for ~T {
+trait plus_uniq<T> {
+    fn +(rhs: ~T) -> ~T;
+}
+
+impl methods<T: copy> of plus_uniq<T> for ~T {
     fn +(rhs: ~T) -> ~T {
         rhs
     }
 }
 
-impl methods for ~int {
+trait minus {
+    fn -(rhs: ~int) -> ~int;
+}
+
+impl methods of minus for ~int {
     fn -(rhs: ~int) -> ~int {
         ~(*self - *rhs)
     }
 }
 
-impl methods for @int {
+trait plus_boxed {
+    fn +(rhs: @int) -> @int;
+}
+
+impl methods of plus_boxed for @int {
     fn +(rhs: @int) -> @int {
         @(*self + *rhs)
     }
diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs
index 2f0b41dc0c6..fb8cdd47f78 100644
--- a/src/test/run-pass/operator-overloading.rs
+++ b/src/test/run-pass/operator-overloading.rs
@@ -1,6 +1,13 @@
 type point = {x: int, y: int};
 
-impl point_ops for point {
+trait ops {
+    fn +(other: point) -> point;
+    fn -(other: point) -> point;
+    fn unary-() -> point;
+    fn [](x: bool) -> int;
+}
+
+impl point_ops of ops for point {
     fn +(other: point) -> point {
         {x: self.x + other.x, y: self.y + other.y}
     }
diff --git a/src/test/run-pass/rcvr-borrowed-to-region.rs b/src/test/run-pass/rcvr-borrowed-to-region.rs
index ddf7081060d..8624e5682a8 100644
--- a/src/test/run-pass/rcvr-borrowed-to-region.rs
+++ b/src/test/run-pass/rcvr-borrowed-to-region.rs
@@ -1,5 +1,9 @@
+trait get {
+    fn get() -> int;
+}
+
 // Note: impl on a slice
-impl foo for &int {
+impl foo of get for &int {
     fn get() -> int {
         ret *self;
     }
@@ -31,4 +35,4 @@ fn main() {
     let y = x.get();
     #debug["y=%d", y];
     assert y == 6;
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/rcvr-borrowed-to-slice.rs b/src/test/run-pass/rcvr-borrowed-to-slice.rs
index 09de19cae45..10f91de8615 100644
--- a/src/test/run-pass/rcvr-borrowed-to-slice.rs
+++ b/src/test/run-pass/rcvr-borrowed-to-slice.rs
@@ -1,5 +1,9 @@
+trait sum {
+    fn sum() -> int;
+}
+
 // Note: impl on a slice
-impl foo for &[int] {
+impl foo of sum for &[int] {
     fn sum() -> int {
         let mut sum = 0;
         for vec::each(self) |e| { sum += e; }
@@ -24,4 +28,4 @@ fn main() {
     let y = x.sum();
     #debug["y==%d", y];
     assert y == 6;
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/regions-self-impls.rs b/src/test/run-pass/regions-self-impls.rs
index d8d33273b8f..07457aa492b 100644
--- a/src/test/run-pass/regions-self-impls.rs
+++ b/src/test/run-pass/regions-self-impls.rs
@@ -1,6 +1,10 @@
 type clam = { chowder: &int };
 
-impl clam for clam {
+trait get_chowder {
+    fn get_chowder() -> &self/int;
+}
+
+impl clam of get_chowder for clam {
     fn get_chowder() -> &self/int { ret self.chowder; }
 }
 
diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs
index 468002e0d5b..580713dab0f 100644
--- a/src/test/run-pass/static-impl.rs
+++ b/src/test/run-pass/static-impl.rs
@@ -1,15 +1,24 @@
 import a::*;
 import b::baz;
 
+trait plus {
+    fn plus() -> int;
+}
+
 mod a {
-    impl foo for uint { fn plus() -> int { self as int + 20 } }
+    impl foo of plus for uint { fn plus() -> int { self as int + 20 } }
 }
 
 mod b {
-    impl baz for ~str { fn plus() -> int { 200 } }
+    impl baz of plus for ~str { fn plus() -> int { 200 } }
+}
+
+trait uint_utils {
+    fn str() -> ~str;
+    fn multi(f: fn(uint));
 }
 
-impl util for uint {
+impl util of uint_utils for uint {
     fn str() -> ~str { uint::str(self) }
     fn multi(f: fn(uint)) {
         let mut c = 0u;
@@ -17,7 +26,13 @@ impl util for uint {
     }
 }
 
-impl util<T> for ~[T] {
+trait vec_utils<T> {
+    fn length_() -> uint;
+    fn iter_(f: fn(T));
+    fn map_<U>(f: fn(T) -> U) -> ~[U];
+}
+
+impl util<T> of vec_utils<T> for ~[T] {
     fn length_() -> uint { vec::len(self) }
     fn iter_(f: fn(T)) { for self.each |x| { f(x); } }
     fn map_<U>(f: fn(T) -> U) -> ~[U] {
@@ -28,8 +43,6 @@ impl util<T> for ~[T] {
 }
 
 fn main() {
-    impl foo for int { fn plus() -> int { self + 10 } }
-    assert 10.plus() == 20;
     assert 10u.plus() == 30;
     assert (~"hi").plus() == 200;