about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-08-27 19:35:44 -0700
committerbors <bors@rust-lang.org>2013-08-27 19:35:44 -0700
commit578e68047736167239c52fa1aba0347011ff1bc3 (patch)
tree00dfacbcaf5bcc846757d37cbf7e9309df699cb8
parent32117132bdaf572bd4a156ec931579646e16d6f0 (diff)
parentaac9d6eee9a1e0b254bf6e035e2e14e5106758bd (diff)
downloadrust-578e68047736167239c52fa1aba0347011ff1bc3.tar.gz
rust-578e68047736167239c52fa1aba0347011ff1bc3.zip
auto merge of #8802 : pcwalton/rust/compile-speed, r=brson
r? @brson
-rw-r--r--doc/rust.md2
-rw-r--r--src/libextra/crypto/cryptoutil.rs3
-rw-r--r--src/libextra/dlist.rs18
-rw-r--r--src/libextra/flate.rs4
-rw-r--r--src/libextra/num/bigint.rs76
-rw-r--r--src/libextra/num/rational.rs29
-rw-r--r--src/libextra/priority_queue.rs19
-rw-r--r--src/libextra/ringbuf.rs2
-rw-r--r--src/libextra/stats.rs2
-rw-r--r--src/libextra/treemap.rs5
-rw-r--r--src/librustc/front/std_inject.rs17
-rw-r--r--src/librustc/front/test.rs31
-rw-r--r--src/librustc/metadata/common.rs6
-rw-r--r--src/librustc/metadata/csearch.rs63
-rw-r--r--src/librustc/metadata/decoder.rs285
-rw-r--r--src/librustc/metadata/encoder.rs136
-rw-r--r--src/librustc/metadata/tydecode.rs21
-rw-r--r--src/librustc/metadata/tyencode.rs1
-rw-r--r--src/librustc/middle/astencode.rs11
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs60
-rw-r--r--src/librustc/middle/borrowck/gather_loans/lifetime.rs12
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs86
-rw-r--r--src/librustc/middle/borrowck/gather_loans/restrictions.rs9
-rw-r--r--src/librustc/middle/borrowck/mod.rs40
-rw-r--r--src/librustc/middle/check_const.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs13
-rw-r--r--src/librustc/middle/privacy.rs21
-rw-r--r--src/librustc/middle/region.rs6
-rw-r--r--src/librustc/middle/resolve.rs605
-rw-r--r--src/librustc/middle/trans/callee.rs17
-rw-r--r--src/librustc/middle/trans/consts.rs4
-rw-r--r--src/librustc/middle/trans/expr.rs8
-rw-r--r--src/librustc/middle/trans/meth.rs8
-rw-r--r--src/librustc/middle/ty.rs166
-rw-r--r--src/librustc/middle/typeck/astconv.rs37
-rw-r--r--src/librustc/middle/typeck/check/_match.rs14
-rw-r--r--src/librustc/middle/typeck/check/method.rs32
-rw-r--r--src/librustc/middle/typeck/check/mod.rs240
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs7
-rw-r--r--src/librustc/middle/typeck/coherence.rs79
-rw-r--r--src/librustc/middle/typeck/collect.rs39
-rw-r--r--src/librustc/middle/typeck/infer/glb.rs22
-rw-r--r--src/librustc/middle/typeck/infer/lub.rs19
-rw-r--r--src/librustc/middle/typeck/infer/sub.rs6
-rw-r--r--src/librustc/util/ppaux.rs1
-rw-r--r--src/libstd/at_vec.rs2
-rw-r--r--src/libstd/cast.rs5
-rw-r--r--src/libstd/cell.rs2
-rw-r--r--src/libstd/cleanup.rs4
-rw-r--r--src/libstd/fmt/mod.rs23
-rw-r--r--src/libstd/hashmap.rs6
-rw-r--r--src/libstd/iterator.rs10
-rw-r--r--src/libstd/logging.rs3
-rw-r--r--src/libstd/num/f32.rs179
-rw-r--r--src/libstd/num/f64.rs186
-rw-r--r--src/libstd/num/float.rs224
-rw-r--r--src/libstd/num/int_macros.rs9
-rw-r--r--src/libstd/num/num.rs24
-rw-r--r--src/libstd/num/uint_macros.rs9
-rw-r--r--src/libstd/os.rs2
-rw-r--r--src/libstd/ptr.rs146
-rw-r--r--src/libstd/rt/borrowck.rs39
-rw-r--r--src/libstd/rt/comm.rs6
-rw-r--r--src/libstd/rt/io/file.rs4
-rw-r--r--src/libstd/rt/io/net/ip.rs51
-rw-r--r--src/libstd/rt/io/net/tcp.rs4
-rw-r--r--src/libstd/rt/io/net/udp.rs5
-rw-r--r--src/libstd/rt/io/timer.rs2
-rw-r--r--src/libstd/rt/local.rs30
-rw-r--r--src/libstd/rt/local_heap.rs7
-rw-r--r--src/libstd/rt/mod.rs8
-rw-r--r--src/libstd/rt/sched.rs25
-rw-r--r--src/libstd/rt/select.rs1
-rw-r--r--src/libstd/rt/task.rs12
-rw-r--r--src/libstd/rt/tube.rs12
-rw-r--r--src/libstd/rt/uv/uvio.rs116
-rw-r--r--src/libstd/select.rs2
-rw-r--r--src/libstd/sys.rs4
-rw-r--r--src/libstd/task/local_data_priv.rs2
-rw-r--r--src/libstd/task/mod.rs12
-rw-r--r--src/libstd/task/spawn.rs10
-rw-r--r--src/libstd/to_bytes.rs9
-rw-r--r--src/libstd/tuple.rs2
-rw-r--r--src/libstd/unstable/atomics.rs3
-rw-r--r--src/libstd/unstable/lang.rs5
-rw-r--r--src/libstd/unstable/sync.rs3
-rw-r--r--src/libstd/util.rs6
-rw-r--r--src/libstd/vec.rs9
-rw-r--r--src/libsyntax/ast.rs38
-rw-r--r--src/libsyntax/ast_util.rs24
-rw-r--r--src/libsyntax/ext/base.rs20
-rw-r--r--src/libsyntax/ext/build.rs52
-rw-r--r--src/libsyntax/ext/concat_idents.rs11
-rw-r--r--src/libsyntax/ext/deriving/rand.rs28
-rw-r--r--src/libsyntax/ext/expand.rs31
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs6
-rw-r--r--src/libsyntax/fold.rs8
-rw-r--r--src/libsyntax/oldvisit.rs6
-rw-r--r--src/libsyntax/parse/mod.rs219
-rw-r--r--src/libsyntax/parse/obsolete.rs11
-rw-r--r--src/libsyntax/parse/parser.rs374
-rw-r--r--src/libsyntax/print/pprust.rs64
-rw-r--r--src/libsyntax/visit.rs6
-rw-r--r--src/test/bench/core-map.rs18
-rw-r--r--src/test/bench/core-set.rs20
-rw-r--r--src/test/compile-fail/bad-mid-path-type-params.rs37
-rw-r--r--src/test/compile-fail/borrowck-alias-mut-base-ptr.rs15
-rw-r--r--src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs12
-rw-r--r--src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs3
-rw-r--r--src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs11
-rw-r--r--src/test/compile-fail/borrowck-lend-flow.rs8
-rw-r--r--src/test/compile-fail/borrowck-loan-vec-content.rs11
-rw-r--r--src/test/compile-fail/borrowck-pat-by-value-binding.rs45
-rw-r--r--src/test/compile-fail/borrowck-uniq-via-lend.rs6
-rw-r--r--src/test/compile-fail/fn-variance-3.rs13
-rw-r--r--src/test/compile-fail/issue-3969.rs25
-rw-r--r--src/test/compile-fail/issue-4096.rs22
-rw-r--r--src/test/compile-fail/map-types.rs4
-rw-r--r--src/test/compile-fail/mutable-huh-ptr-assign.rs23
-rw-r--r--src/test/compile-fail/prim-with-args.rs24
-rw-r--r--src/test/compile-fail/private-variant-xc.rs1
-rw-r--r--src/test/compile-fail/regions-bounds.rs4
-rw-r--r--src/test/compile-fail/resolve-inconsistent-binding-mode.rs7
-rw-r--r--src/test/compile-fail/static-method-privacy.rs2
-rw-r--r--src/test/compile-fail/xc-private-method.rs4
-rw-r--r--src/test/debug-info/generic-trait-generic-static-default-method.rs2
-rw-r--r--src/test/debug-info/trait-generic-static-default-method.rs2
-rw-r--r--src/test/run-pass/auto-ref-slice-plus-ref.rs12
-rw-r--r--src/test/run-pass/autoderef-and-borrow-method-receiver.rs2
-rw-r--r--src/test/run-pass/borrowck-pat-enum.rs (renamed from src/test/compile-fail/borrowck-pat-enum.rs)25
-rw-r--r--src/test/run-pass/borrowck-uniq-via-ref.rs (renamed from src/test/compile-fail/borrowck-uniq-via-ref.rs)13
-rw-r--r--src/test/run-pass/class-impl-very-parameterized-trait.rs4
-rw-r--r--src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs6
-rw-r--r--src/test/run-pass/const-vec-syntax.rs2
-rw-r--r--src/test/run-pass/deriving-zero.rs3
-rw-r--r--src/test/run-pass/float-nan.rs7
-rw-r--r--src/test/run-pass/issue-3026.rs2
-rw-r--r--src/test/run-pass/issue-6898.rs2
-rw-r--r--src/test/run-pass/mid-path-type-params.rs33
-rw-r--r--src/test/run-pass/objects-owned-object-borrowed-method-header.rs2
-rw-r--r--src/test/run-pass/trait-bounds-in-arc.rs2
-rw-r--r--src/test/run-pass/trait-default-method-xc.rs2
-rw-r--r--src/test/run-pass/trait-static-method-overwriting.rs6
143 files changed, 3067 insertions, 1780 deletions
diff --git a/doc/rust.md b/doc/rust.md
index 7ac0527e47d..08c04c6c888 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2230,7 +2230,7 @@ Some examples of call expressions:
 # fn add(x: int, y: int) -> int { 0 }
 
 let x: int = add(1, 2);
-let pi = FromStr::from_str::<f32>("3.14");
+let pi: Option<f32> = FromStr::from_str("3.14");
 ~~~~
 
 ### Lambda expressions
diff --git a/src/libextra/crypto/cryptoutil.rs b/src/libextra/crypto/cryptoutil.rs
index d4d43558110..9516517d9f7 100644
--- a/src/libextra/crypto/cryptoutil.rs
+++ b/src/libextra/crypto/cryptoutil.rs
@@ -420,6 +420,7 @@ mod test {
     #[test]
     #[should_fail]
     fn test_add_bytes_to_bits_tuple_overflow2() {
-        add_bytes_to_bits_tuple::<u64>((Bounded::max_value::<u64>() - 1, 0), 0x8000000000000000);
+        let value: u64 = Bounded::max_value();
+        add_bytes_to_bits_tuple::<u64>((value - 1, 0), 0x8000000000000000);
     }
 }
diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 076e86dd5b0..8e641073637 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -661,7 +661,7 @@ mod tests {
 
     #[test]
     fn test_basic() {
-        let mut m = DList::new::<~int>();
+        let mut m: DList<~int> = DList::new();
         assert_eq!(m.pop_front(), None);
         assert_eq!(m.pop_back(), None);
         assert_eq!(m.pop_front(), None);
@@ -768,7 +768,7 @@ mod tests {
 
     #[test]
     fn test_rotate() {
-        let mut n = DList::new::<int>();
+        let mut n: DList<int> = DList::new();
         n.rotate_backward(); check_links(&n);
         assert_eq!(n.len(), 0);
         n.rotate_forward(); check_links(&n);
@@ -1033,7 +1033,7 @@ mod tests {
 
     #[cfg(test)]
     fn fuzz_test(sz: int) {
-        let mut m = DList::new::<int>();
+        let mut m: DList<int> = DList::new();
         let mut v = ~[];
         for i in range(0, sz) {
             check_links(&m);
@@ -1078,7 +1078,7 @@ mod tests {
 
     #[bench]
     fn bench_push_front(b: &mut test::BenchHarness) {
-        let mut m = DList::new::<int>();
+        let mut m: DList<int> = DList::new();
         do b.iter {
             m.push_front(0);
         }
@@ -1086,7 +1086,7 @@ mod tests {
 
     #[bench]
     fn bench_push_back(b: &mut test::BenchHarness) {
-        let mut m = DList::new::<int>();
+        let mut m: DList<int> = DList::new();
         do b.iter {
             m.push_back(0);
         }
@@ -1094,7 +1094,7 @@ mod tests {
 
     #[bench]
     fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
-        let mut m = DList::new::<int>();
+        let mut m: DList<int> = DList::new();
         do b.iter {
             m.push_back(0);
             m.pop_back();
@@ -1103,7 +1103,7 @@ mod tests {
 
     #[bench]
     fn bench_push_front_pop_front(b: &mut test::BenchHarness) {
-        let mut m = DList::new::<int>();
+        let mut m: DList<int> = DList::new();
         do b.iter {
             m.push_front(0);
             m.pop_front();
@@ -1112,7 +1112,7 @@ mod tests {
 
     #[bench]
     fn bench_rotate_forward(b: &mut test::BenchHarness) {
-        let mut m = DList::new::<int>();
+        let mut m: DList<int> = DList::new();
         m.push_front(0);
         m.push_front(1);
         do b.iter {
@@ -1122,7 +1122,7 @@ mod tests {
 
     #[bench]
     fn bench_rotate_backward(b: &mut test::BenchHarness) {
-        let mut m = DList::new::<int>();
+        let mut m: DList<int> = DList::new();
         m.push_front(0);
         m.push_front(1);
         do b.iter {
diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs
index 53088500129..65d4f79c640 100644
--- a/src/libextra/flate.rs
+++ b/src/libextra/flate.rs
@@ -25,13 +25,13 @@ pub mod rustrt {
 
     #[link_name = "rustrt"]
     extern {
-        pub fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
+        pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
                                           src_buf_len: size_t,
                                           pout_len: *mut size_t,
                                           flags: c_int)
                                           -> *c_void;
 
-        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
+        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
                                             src_buf_len: size_t,
                                             pout_len: *mut size_t,
                                             flags: c_int)
diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs
index 9222dea13c4..5fd9690d9b0 100644
--- a/src/libextra/num/bigint.rs
+++ b/src/libextra/num/bigint.rs
@@ -359,7 +359,7 @@ impl Integer for BigUint {
 
         fn div_mod_floor_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
             let mut m = a;
-            let mut d = Zero::zero::<BigUint>();
+            let mut d: BigUint = Zero::zero();
             let mut n = 1;
             while m >= b {
                 let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
@@ -411,8 +411,9 @@ impl Integer for BigUint {
             if shift == 0 {
                 return (BigUint::new(d), One::one(), (*b).clone());
             }
+            let one: BigUint = One::one();
             return (BigUint::from_slice(d).shl_unit(shift),
-                    One::one::<BigUint>().shl_unit(shift),
+                    one.shl_unit(shift),
                     b.shl_unit(shift));
         }
     }
@@ -1168,8 +1169,8 @@ mod biguint_tests {
     #[test]
     fn test_shl() {
         fn check(s: &str, shift: uint, ans: &str) {
-            let bu = (FromStrRadix::from_str_radix::<BigUint>(s, 16).unwrap() << shift)
-                .to_str_radix(16);
+            let opt_biguint: Option<BigUint> = FromStrRadix::from_str_radix(s, 16);
+            let bu = (opt_biguint.unwrap() << shift).to_str_radix(16);
             assert_eq!(bu.as_slice(), ans);
         }
 
@@ -1206,8 +1207,9 @@ mod biguint_tests {
     #[test]
     fn test_shr() {
         fn check(s: &str, shift: uint, ans: &str) {
-            let bu = (FromStrRadix::from_str_radix::<BigUint>(s, 16).unwrap() >> shift)
-                .to_str_radix(16);
+            let opt_biguint: Option<BigUint> =
+                FromStrRadix::from_str_radix(s, 16);
+            let bu = (opt_biguint.unwrap() >> shift).to_str_radix(16);
             assert_eq!(bu.as_slice(), ans);
         }
 
@@ -1445,11 +1447,18 @@ mod biguint_tests {
 
     #[test]
     fn test_is_even() {
-        assert!(FromStr::from_str::<BigUint>("1").unwrap().is_odd());
-        assert!(FromStr::from_str::<BigUint>("2").unwrap().is_even());
-        assert!(FromStr::from_str::<BigUint>("1000").unwrap().is_even());
-        assert!(FromStr::from_str::<BigUint>("1000000000000000000000").unwrap().is_even());
-        assert!(FromStr::from_str::<BigUint>("1000000000000000000001").unwrap().is_odd());
+        let one: Option<BigUint> = FromStr::from_str("1");
+        let two: Option<BigUint> = FromStr::from_str("2");
+        let thousand: Option<BigUint> = FromStr::from_str("1000");
+        let big: Option<BigUint> =
+            FromStr::from_str("1000000000000000000000");
+        let bigger: Option<BigUint> =
+            FromStr::from_str("1000000000000000000001");
+        assert!(one.unwrap().is_odd());
+        assert!(two.unwrap().is_even());
+        assert!(thousand.unwrap().is_even());
+        assert!(big.unwrap().is_even());
+        assert!(bigger.unwrap().is_odd());
         assert!((BigUint::from_uint(1) << 64).is_even());
         assert!(((BigUint::from_uint(1) << 64) + BigUint::from_uint(1)).is_odd());
     }
@@ -1534,15 +1543,19 @@ mod biguint_tests {
             }
         }
 
-        assert_eq!(FromStrRadix::from_str_radix::<BigUint>("Z", 10), None);
-        assert_eq!(FromStrRadix::from_str_radix::<BigUint>("_", 2), None);
-        assert_eq!(FromStrRadix::from_str_radix::<BigUint>("-1", 10), None);
+        let zed: Option<BigUint> = FromStrRadix::from_str_radix("Z", 10);
+        assert_eq!(zed, None);
+        let blank: Option<BigUint> = FromStrRadix::from_str_radix("_", 2);
+        assert_eq!(blank, None);
+        let minus_one: Option<BigUint> = FromStrRadix::from_str_radix("-1",
+                                                                      10);
+        assert_eq!(minus_one, None);
     }
 
     #[test]
     fn test_factor() {
         fn factor(n: uint) -> BigUint {
-            let mut f= One::one::<BigUint>();
+            let mut f: BigUint = One::one();
             for i in range(2, n + 1) {
                 // FIXME(#6102): Assignment operator for BigInt causes ICE
                 // f *= BigUint::from_uint(i);
@@ -1939,17 +1952,24 @@ mod bigint_tests {
 
     #[test]
     fn test_abs_sub() {
-        assert_eq!((-One::one::<BigInt>()).abs_sub(&One::one()), Zero::zero());
-        assert_eq!(One::one::<BigInt>().abs_sub(&One::one()), Zero::zero());
-        assert_eq!(One::one::<BigInt>().abs_sub(&Zero::zero()), One::one());
-        assert_eq!(One::one::<BigInt>().abs_sub(&-One::one::<BigInt>()),
-                   IntConvertible::from_int(2));
+        let zero: BigInt = Zero::zero();
+        let one: BigInt = One::one();
+        assert_eq!((-one).abs_sub(&one), zero);
+        let one: BigInt = One::one();
+        let zero: BigInt = Zero::zero();
+        assert_eq!(one.abs_sub(&one), zero);
+        let one: BigInt = One::one();
+        let zero: BigInt = Zero::zero();
+        assert_eq!(one.abs_sub(&zero), one);
+        let one: BigInt = One::one();
+        assert_eq!(one.abs_sub(&-one), IntConvertible::from_int(2));
     }
 
     #[test]
     fn test_to_str_radix() {
         fn check(n: int, ans: &str) {
-            assert!(ans == IntConvertible::from_int::<BigInt>(n).to_str_radix(10));
+            let n: BigInt = IntConvertible::from_int(n);
+            assert!(ans == n.to_str_radix(10));
         }
         check(10, "10");
         check(1, "1");
@@ -1962,7 +1982,10 @@ mod bigint_tests {
     #[test]
     fn test_from_str_radix() {
         fn check(s: &str, ans: Option<int>) {
-            let ans = ans.map_move(|n| IntConvertible::from_int::<BigInt>(n));
+            let ans = ans.map_move(|n| {
+                let x: BigInt = IntConvertible::from_int(n);
+                x
+            });
             assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
         }
         check("10", Some(10));
@@ -1980,7 +2003,8 @@ mod bigint_tests {
             BigInt::new(Minus, ~[1, 1, 1]));
         assert!(-BigInt::new(Minus, ~[1, 1, 1]) ==
             BigInt::new(Plus,  ~[1, 1, 1]));
-        assert_eq!(-Zero::zero::<BigInt>(), Zero::zero::<BigInt>());
+        let zero: BigInt = Zero::zero();
+        assert_eq!(-zero, zero);
     }
 }
 
@@ -1992,7 +2016,7 @@ mod bench {
     use extra::test::BenchHarness;
 
     fn factorial(n: uint) -> BigUint {
-        let mut f = One::one::<BigUint>();
+        let mut f: BigUint = One::one();
         for i in iterator::range_inclusive(1, n) {
             f = f * BigUint::from_uint(i);
         }
@@ -2000,8 +2024,8 @@ mod bench {
     }
 
     fn fib(n: uint) -> BigUint {
-        let mut f0 = Zero::zero::<BigUint>();
-        let mut f1 = One::one::<BigUint>();
+        let mut f0: BigUint = Zero::zero();
+        let mut f1: BigUint = One::one();
         for _ in range(0, n) {
             let f2 = f0 + f1;
             f0 = util::replace(&mut f1, f2);
diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs
index 60dd36a3b88..41e9a488bf8 100644
--- a/src/libextra/num/rational.rs
+++ b/src/libextra/num/rational.rs
@@ -269,9 +269,13 @@ impl<T: FromStr + Clone + Integer + Ord>
     /// Parses `numer/denom`.
     fn from_str(s: &str) -> Option<Ratio<T>> {
         let split: ~[&str] = s.splitn_iter('/', 1).collect();
-        if split.len() < 2 { return None; }
-        do FromStr::from_str::<T>(split[0]).chain |a| {
-            do FromStr::from_str::<T>(split[1]).chain |b| {
+        if split.len() < 2 {
+            return None
+        }
+        let a_option: Option<T> = FromStr::from_str(split[0]);
+        do a_option.chain |a| {
+            let b_option: Option<T> = FromStr::from_str(split[1]);
+            do b_option.chain |b| {
                 Some(Ratio::new(a.clone(), b.clone()))
             }
         }
@@ -282,10 +286,15 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
     /// Parses `numer/denom` where the numbers are in base `radix`.
     fn from_str_radix(s: &str, radix: uint) -> Option<Ratio<T>> {
         let split: ~[&str] = s.splitn_iter('/', 1).collect();
-        if split.len() < 2 { None }
-        else {
-            do FromStrRadix::from_str_radix::<T>(split[0], radix).chain |a| {
-                do FromStrRadix::from_str_radix::<T>(split[1], radix).chain |b| {
+        if split.len() < 2 {
+            None
+        } else {
+            let a_option: Option<T> = FromStrRadix::from_str_radix(split[0],
+                                                                   radix);
+            do a_option.chain |a| {
+                let b_option: Option<T> =
+                    FromStrRadix::from_str_radix(split[1], radix);
+                do b_option.chain |b| {
                     Some(Ratio::new(a.clone(), b.clone()))
                 }
             }
@@ -496,7 +505,8 @@ mod test {
     #[test]
     fn test_from_str_fail() {
         fn test(s: &str) {
-            assert_eq!(FromStr::from_str::<Rational>(s), None);
+            let rational: Option<Rational> = FromStr::from_str(s);
+            assert_eq!(rational, None);
         }
 
         let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"];
@@ -536,7 +546,8 @@ mod test {
     #[test]
     fn test_from_str_radix_fail() {
         fn test(s: &str) {
-            assert_eq!(FromStrRadix::from_str_radix::<Rational>(s, 3), None);
+            let radix: Option<Rational> = FromStrRadix::from_str_radix(s, 3);
+            assert_eq!(radix, None);
         }
 
         let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"];
diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs
index a9341a8075d..b085981aabb 100644
--- a/src/libextra/priority_queue.rs
+++ b/src/libextra/priority_queue.rs
@@ -338,27 +338,36 @@ mod tests {
 
     #[test]
     #[should_fail]
-    fn test_empty_pop() { let mut heap = PriorityQueue::new::<int>(); heap.pop(); }
+    fn test_empty_pop() {
+        let mut heap: PriorityQueue<int> = PriorityQueue::new();
+        heap.pop();
+    }
 
     #[test]
     fn test_empty_maybe_pop() {
-        let mut heap = PriorityQueue::new::<int>();
+        let mut heap: PriorityQueue<int> = PriorityQueue::new();
         assert!(heap.maybe_pop().is_none());
     }
 
     #[test]
     #[should_fail]
-    fn test_empty_top() { let empty = PriorityQueue::new::<int>(); empty.top(); }
+    fn test_empty_top() {
+        let empty: PriorityQueue<int> = PriorityQueue::new();
+        empty.top();
+    }
 
     #[test]
     fn test_empty_maybe_top() {
-        let empty = PriorityQueue::new::<int>();
+        let empty: PriorityQueue<int> = PriorityQueue::new();
         assert!(empty.maybe_top().is_none());
     }
 
     #[test]
     #[should_fail]
-    fn test_empty_replace() { let mut heap = PriorityQueue::new(); heap.replace(5); }
+    fn test_empty_replace() {
+        let mut heap: PriorityQueue<int> = PriorityQueue::new();
+        heap.replace(5);
+    }
 
     #[test]
     fn test_from_iter() {
diff --git a/src/libextra/ringbuf.rs b/src/libextra/ringbuf.rs
index a38cb580c50..4f2755374af 100644
--- a/src/libextra/ringbuf.rs
+++ b/src/libextra/ringbuf.rs
@@ -483,7 +483,7 @@ mod tests {
     #[bench]
     fn bench_new(b: &mut test::BenchHarness) {
         do b.iter {
-            let _ = RingBuf::new::<u64>();
+            let _: RingBuf<u64> = RingBuf::new();
         }
     }
 
diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs
index 0cea4c1ac6c..2b6c53b3c86 100644
--- a/src/libextra/stats.rs
+++ b/src/libextra/stats.rs
@@ -368,7 +368,7 @@ pub fn write_boxplot(w: @io::Writer, s: &Summary, width_hint: uint) {
 /// Returns a HashMap with the number of occurrences of every element in the
 /// sequence that the iterator exposes.
 pub fn freq_count<T: Iterator<U>, U: Eq+Hash>(mut iter: T) -> hashmap::HashMap<U, uint> {
-    let mut map = hashmap::HashMap::new::<U, uint>();
+    let mut map: hashmap::HashMap<U,uint> = hashmap::HashMap::new();
     for elem in iter {
         map.insert_or_update_with(elem, 1, |_, count| *count += 1);
     }
diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs
index 118754ec028..307de43a067 100644
--- a/src/libextra/treemap.rs
+++ b/src/libextra/treemap.rs
@@ -879,7 +879,8 @@ mod test_treemap {
 
     #[test]
     fn find_empty() {
-        let m = TreeMap::new::<int, int>(); assert!(m.find(&5) == None);
+        let m: TreeMap<int,int> = TreeMap::new();
+        assert!(m.find(&5) == None);
     }
 
     #[test]
@@ -1006,7 +1007,7 @@ mod test_treemap {
 
     #[test]
     fn test_rand_int() {
-        let mut map = TreeMap::new::<int, int>();
+        let mut map: TreeMap<int,int> = TreeMap::new();
         let mut ctrl = ~[];
 
         check_equal(ctrl, &map);
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index 2a61ea28e0c..429a1c35b34 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -17,6 +17,7 @@ use syntax::attr;
 use syntax::codemap::dummy_sp;
 use syntax::codemap;
 use syntax::fold;
+use syntax::opt_vec;
 
 static STD_VERSION: &'static str = "0.8-pre";
 
@@ -90,12 +91,18 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate {
             let prelude_path = ast::Path {
                 span: dummy_sp(),
                 global: false,
-                idents: ~[
-                    sess.ident_of("std"),
-                    sess.ident_of("prelude")
+                segments: ~[
+                    ast::PathSegment {
+                        identifier: sess.ident_of("std"),
+                        lifetime: None,
+                        types: opt_vec::Empty,
+                    },
+                    ast::PathSegment {
+                        identifier: sess.ident_of("prelude"),
+                        lifetime: None,
+                        types: opt_vec::Empty,
+                    },
                 ],
-                rp: None,
-                types: ~[]
             };
 
             let vp = @spanned(ast::view_path_glob(prelude_path, n2));
diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs
index 0aacd4c5063..a341db75393 100644
--- a/src/librustc/front/test.rs
+++ b/src/librustc/front/test.rs
@@ -16,14 +16,15 @@ use front::config;
 
 use std::vec;
 use syntax::ast_util::*;
+use syntax::attr::AttrMetaMethods;
 use syntax::attr;
 use syntax::codemap::{dummy_sp, span, ExpnInfo, NameAndSpan};
 use syntax::codemap;
 use syntax::ext::base::ExtCtxt;
 use syntax::fold;
+use syntax::opt_vec;
 use syntax::print::pprust;
 use syntax::{ast, ast_util};
-use syntax::attr::AttrMetaMethods;
 
 type node_id_gen = @fn() -> ast::NodeId;
 
@@ -383,19 +384,27 @@ fn nospan<T>(t: T) -> codemap::spanned<T> {
 }
 
 fn path_node(ids: ~[ast::ident]) -> ast::Path {
-    ast::Path { span: dummy_sp(),
-                global: false,
-                idents: ids,
-                rp: None,
-                types: ~[] }
+    ast::Path {
+        span: dummy_sp(),
+        global: false,
+        segments: ids.move_iter().map(|identifier| ast::PathSegment {
+            identifier: identifier,
+            lifetime: None,
+            types: opt_vec::Empty,
+        }).collect()
+    }
 }
 
 fn path_node_global(ids: ~[ast::ident]) -> ast::Path {
-    ast::Path { span: dummy_sp(),
-                 global: true,
-                 idents: ids,
-                 rp: None,
-                 types: ~[] }
+    ast::Path {
+        span: dummy_sp(),
+        global: true,
+        segments: ids.move_iter().map(|identifier| ast::PathSegment {
+            identifier: identifier,
+            lifetime: None,
+            types: opt_vec::Empty,
+        }).collect()
+    }
 }
 
 #[cfg(stage0)]
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index f2d8b68faa6..8af53586594 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -182,6 +182,12 @@ pub static tag_misc_info_crate_items: uint = 0x80;
 pub static tag_item_method_provided_source: uint = 0x81;
 pub static tag_item_impl_vtables: uint = 0x82;
 
+pub static tag_impls: uint = 0x83;
+pub static tag_impls_impl: uint = 0x84;
+
+pub static tag_items_data_item_inherent_impl: uint = 0x85;
+pub static tag_items_data_item_extension_impl: uint = 0x86;
+
 pub struct LinkMeta {
     name: @str,
     vers: @str,
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 317b9cf6ce3..3ad69ff4da0 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -49,16 +49,34 @@ pub fn each_lang_item(cstore: @mut cstore::CStore,
     decoder::each_lang_item(crate_data, f)
 }
 
-/// Iterates over all the paths in the given crate.
-pub fn each_path(cstore: @mut cstore::CStore,
-                 cnum: ast::CrateNum,
-                 f: &fn(&str, decoder::def_like, ast::visibility) -> bool)
-                 -> bool {
+/// Iterates over each child of the given item.
+pub fn each_child_of_item(cstore: @mut cstore::CStore,
+                          def_id: ast::def_id,
+                          callback: &fn(decoder::def_like, ast::ident)) {
+    let crate_data = cstore::get_crate_data(cstore, def_id.crate);
+    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
+        cstore::get_crate_data(cstore, cnum)
+    };
+    decoder::each_child_of_item(cstore.intr,
+                                crate_data,
+                                def_id.node,
+                                get_crate_data,
+                                callback)
+}
+
+/// Iterates over each top-level crate item.
+pub fn each_top_level_item_of_crate(cstore: @mut cstore::CStore,
+                                    cnum: ast::CrateNum,
+                                    callback: &fn(decoder::def_like,
+                                                  ast::ident)) {
     let crate_data = cstore::get_crate_data(cstore, cnum);
     let get_crate_data: decoder::GetCrateDataCb = |cnum| {
         cstore::get_crate_data(cstore, cnum)
     };
-    decoder::each_path(cstore.intr, crate_data, get_crate_data, f)
+    decoder::each_top_level_item_of_crate(cstore.intr,
+                                          crate_data,
+                                          get_crate_data,
+                                          callback)
 }
 
 pub fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
@@ -246,3 +264,36 @@ pub fn get_link_args_for_crate(cstore: @mut cstore::CStore,
     let cdata = cstore::get_crate_data(cstore, crate_num);
     decoder::get_link_args_for_crate(cdata)
 }
+
+pub fn each_impl(cstore: @mut cstore::CStore,
+                 crate_num: ast::CrateNum,
+                 callback: &fn(ast::def_id)) {
+    let cdata = cstore::get_crate_data(cstore, crate_num);
+    decoder::each_impl(cdata, callback)
+}
+
+pub fn each_implementation_for_type(cstore: @mut cstore::CStore,
+                                    def_id: ast::def_id,
+                                    callback: &fn(ast::def_id)) {
+    let cdata = cstore::get_crate_data(cstore, def_id.crate);
+    decoder::each_implementation_for_type(cdata, def_id.node, callback)
+}
+
+pub fn each_implementation_for_trait(cstore: @mut cstore::CStore,
+                                     def_id: ast::def_id,
+                                     callback: &fn(ast::def_id)) {
+    let cdata = cstore::get_crate_data(cstore, def_id.crate);
+    decoder::each_implementation_for_trait(cdata, def_id.node, callback)
+}
+
+/// If the given def ID describes a method belonging to a trait (either a
+/// default method or an implementation of a trait method), returns the ID of
+/// the trait that the method belongs to. Otherwise, returns `None`.
+pub fn get_trait_of_method(cstore: @mut cstore::CStore,
+                           def_id: ast::def_id,
+                           tcx: ty::ctxt)
+                           -> Option<ast::def_id> {
+    let cdata = cstore::get_crate_data(cstore, def_id.crate);
+    decoder::get_trait_of_method(cdata, def_id.node, tcx)
+}
+
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 3fdd1587c0d..336c07c9d6e 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -20,6 +20,7 @@ use metadata::decoder;
 use metadata::tydecode::{parse_ty_data, parse_def_id,
                          parse_type_param_def_data,
                          parse_bare_fn_ty_data, parse_trait_ref_data};
+use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty;
 use middle::typeck;
 use middle::astencode::vtable_decoder_helpers;
@@ -39,7 +40,7 @@ use syntax::ast_map;
 use syntax::attr;
 use syntax::parse::token::{ident_interner, special_idents};
 use syntax::print::pprust;
-use syntax::{ast, ast_util};
+use syntax::ast;
 use syntax::codemap;
 use syntax::parse::token;
 
@@ -335,15 +336,19 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::CrateNum)
             let purity = if fam == UnsafeStaticMethod { ast::unsafe_fn } else
                 { ast::impure_fn };
             // def_static_method carries an optional field of its enclosing
-            // *trait*, but not an inclosing Impl (if this is an inherent
-            // static method). So we need to detect whether this is in
-            // a trait or not, which we do through the mildly hacky
-            // way of checking whether there is a trait_method_sort.
-            let trait_did_opt = if reader::maybe_get_doc(
+            // trait or enclosing impl (if this is an inherent static method).
+            // So we need to detect whether this is in a trait or not, which
+            // we do through the mildly hacky way of checking whether there is
+            // a trait_method_sort.
+            let provenance = if reader::maybe_get_doc(
                   item, tag_item_trait_method_sort).is_some() {
-                Some(item_reqd_and_translated_parent_item(cnum, item))
-            } else { None };
-            dl_def(ast::def_static_method(did, trait_did_opt, purity))
+                ast::FromTrait(item_reqd_and_translated_parent_item(cnum,
+                                                                    item))
+            } else {
+                ast::FromImpl(item_reqd_and_translated_parent_item(cnum,
+                                                                   item))
+            };
+            dl_def(ast::def_static_method(did, provenance, purity))
         }
         Type | ForeignType => dl_def(ast::def_ty(did)),
         Mod => dl_def(ast::def_mod(did)),
@@ -698,33 +703,164 @@ impl<'self> EachItemContext<'self> {
     }
 }
 
-/// Iterates over all the paths in the given crate.
-pub fn each_path(intr: @ident_interner,
-                 cdata: cmd,
-                 get_crate_data: GetCrateDataCb,
-                 f: &fn(&str, def_like, ast::visibility) -> bool)
-                 -> bool {
-    // FIXME #4572: This function needs to be nuked, as it's impossible to
-    // make fast. It's the source of most of the performance problems when
-    // compiling small crates.
+fn each_child_of_item_or_crate(intr: @ident_interner,
+                               cdata: cmd,
+                               item_doc: ebml::Doc,
+                               get_crate_data: GetCrateDataCb,
+                               callback: &fn(def_like, ast::ident)) {
+    // Iterate over all children.
+    let _ = do reader::tagged_docs(item_doc, tag_mod_child) |child_info_doc| {
+        let child_def_id = reader::with_doc_data(child_info_doc,
+                                                 parse_def_id);
+        let child_def_id = translate_def_id(cdata, child_def_id);
+
+        // This item may be in yet another crate if it was the child of a
+        // reexport.
+        let other_crates_items = if child_def_id.crate == cdata.cnum {
+            reader::get_doc(reader::Doc(cdata.data), tag_items)
+        } else {
+            let crate_data = get_crate_data(child_def_id.crate);
+            reader::get_doc(reader::Doc(crate_data.data), tag_items)
+        };
+
+        // Get the item.
+        match maybe_find_item(child_def_id.node, other_crates_items) {
+            None => {}
+            Some(child_item_doc) => {
+                // Hand off the item to the callback.
+                let child_name = item_name(intr, child_item_doc);
+                let def_like = item_to_def_like(child_item_doc,
+                                                child_def_id,
+                                                cdata.cnum);
+                callback(def_like, child_name);
+
+            }
+        }
+
+        true
+    };
+
+    // As a special case, iterate over all static methods of
+    // associated implementations too. This is a bit of a botch.
+    // --pcwalton
+    let _ = do reader::tagged_docs(item_doc,
+                                   tag_items_data_item_inherent_impl)
+            |inherent_impl_def_id_doc| {
+        let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc,
+                                               cdata);
+        let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
+        match maybe_find_item(inherent_impl_def_id.node, items) {
+            None => {}
+            Some(inherent_impl_doc) => {
+                let _ = do reader::tagged_docs(inherent_impl_doc,
+                                               tag_item_impl_method)
+                        |impl_method_def_id_doc| {
+                    let impl_method_def_id =
+                        reader::with_doc_data(impl_method_def_id_doc,
+                                              parse_def_id);
+                    let impl_method_def_id =
+                        translate_def_id(cdata, impl_method_def_id);
+                    match maybe_find_item(impl_method_def_id.node, items) {
+                        None => {}
+                        Some(impl_method_doc) => {
+                            match item_family(impl_method_doc) {
+                                StaticMethod | UnsafeStaticMethod => {
+                                    // Hand off the static method
+                                    // to the callback.
+                                    let static_method_name =
+                                        item_name(intr, impl_method_doc);
+                                    let static_method_def_like =
+                                        item_to_def_like(impl_method_doc,
+                                                         impl_method_def_id,
+                                                         cdata.cnum);
+                                    callback(static_method_def_like,
+                                             static_method_name);
+                                }
+                                _ => {}
+                            }
+                        }
+                    }
+
+                    true
+                };
+            }
+        }
+
+        true
+    };
+
+    // Iterate over all reexports.
+    let _ = do each_reexport(item_doc) |reexport_doc| {
+        let def_id_doc = reader::get_doc(reexport_doc,
+                                         tag_items_data_item_reexport_def_id);
+        let child_def_id = reader::with_doc_data(def_id_doc,
+                                                 parse_def_id);
+        let child_def_id = translate_def_id(cdata, child_def_id);
+
+        let name_doc = reader::get_doc(reexport_doc,
+                                       tag_items_data_item_reexport_name);
+        let name = name_doc.as_str_slice();
+
+        // This reexport may be in yet another crate.
+        let other_crates_items = if child_def_id.crate == cdata.cnum {
+            reader::get_doc(reader::Doc(cdata.data), tag_items)
+        } else {
+            let crate_data = get_crate_data(child_def_id.crate);
+            reader::get_doc(reader::Doc(crate_data.data), tag_items)
+        };
+
+        // Get the item.
+        match maybe_find_item(child_def_id.node, other_crates_items) {
+            None => {}
+            Some(child_item_doc) => {
+                // Hand off the item to the callback.
+                let def_like = item_to_def_like(child_item_doc,
+                                                child_def_id,
+                                                cdata.cnum);
+                callback(def_like, token::str_to_ident(name));
+            }
+        }
+
+        true
+    };
+}
+
+/// Iterates over each child of the given item.
+pub fn each_child_of_item(intr: @ident_interner,
+                          cdata: cmd,
+                          id: ast::NodeId,
+                          get_crate_data: GetCrateDataCb,
+                          callback: &fn(def_like, ast::ident)) {
+    // Find the item.
+    let root_doc = reader::Doc(cdata.data);
+    let items = reader::get_doc(root_doc, tag_items);
+    let item_doc = match maybe_find_item(id, items) {
+        None => return,
+        Some(item_doc) => item_doc,
+    };
 
+    each_child_of_item_or_crate(intr,
+                                cdata,
+                                item_doc,
+                                get_crate_data,
+                                callback)
+}
+
+/// Iterates over all the top-level crate items.
+pub fn each_top_level_item_of_crate(intr: @ident_interner,
+                                    cdata: cmd,
+                                    get_crate_data: GetCrateDataCb,
+                                    callback: &fn(def_like, ast::ident)) {
     let root_doc = reader::Doc(cdata.data);
     let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
     let crate_items_doc = reader::get_doc(misc_info_doc,
                                           tag_misc_info_crate_items);
 
-    let mut path_builder = ~"";
-
-    let mut context = EachItemContext {
-        intr: intr,
-        cdata: cdata,
-        get_crate_data: get_crate_data,
-        path_builder: &mut path_builder,
-        callback: f,
-    };
-
-    // Iterate over all top-level crate items.
-    context.each_child_of_module_or_crate(crate_items_doc)
+    each_child_of_item_or_crate(intr,
+                                cdata,
+                                crate_items_doc,
+                                get_crate_data,
+                                callback)
 }
 
 pub fn get_item_path(cdata: cmd, id: ast::NodeId) -> ast_map::path {
@@ -804,12 +940,9 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
 fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
     fn get_mutability(ch: u8) -> ast::mutability {
         match ch as char {
-            'i' => { ast::m_imm }
-            'm' => { ast::m_mutbl }
-            'c' => { ast::m_const }
-            _ => {
-                fail!("unknown mutability character: `%c`", ch as char)
-            }
+            'i' => ast::m_imm,
+            'm' => ast::m_mutbl,
+            _ => fail!("unknown mutability character: `%c`", ch as char),
         }
     }
 
@@ -876,8 +1009,15 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
 {
     let method_doc = lookup_item(id, cdata.data);
     let def_id = item_def_id(method_doc, cdata);
+
     let container_id = item_reqd_and_translated_parent_item(cdata.cnum,
                                                             method_doc);
+    let container_doc = lookup_item(container_id.node, cdata.data);
+    let container = match item_family(container_doc) {
+        Trait => TraitContainer(container_id),
+        _ => ImplContainer(container_id),
+    };
+
     let name = item_name(intr, method_doc);
     let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
                                              tag_item_method_tps);
@@ -898,7 +1038,7 @@ pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
         explicit_self,
         vis,
         def_id,
-        container_id,
+        container,
         provided_source
     )
 }
@@ -1267,21 +1407,6 @@ pub fn get_crate_vers(data: @~[u8]) -> @str {
     }
 }
 
-fn iter_crate_items(intr: @ident_interner, cdata: cmd,
-                    get_crate_data: GetCrateDataCb,
-                    proc: &fn(path: &str, ast::def_id)) {
-    do each_path(intr, cdata, get_crate_data) |path_string, def_like, _| {
-        match def_like {
-            dl_impl(*) | dl_field => {}
-            dl_def(def) => {
-                proc(path_string,
-                     ast_util::def_id_of_def(def))
-            }
-        }
-        true
-    };
-}
-
 pub fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8],
                            out: @io::Writer) {
     let hash = get_crate_hash(bytes);
@@ -1315,3 +1440,59 @@ pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] {
     };
     result
 }
+
+pub fn each_impl(cdata: cmd, callback: &fn(ast::def_id)) {
+    let impls_doc = reader::get_doc(reader::Doc(cdata.data), tag_impls);
+    let _ = do reader::tagged_docs(impls_doc, tag_impls_impl) |impl_doc| {
+        callback(item_def_id(impl_doc, cdata));
+        true
+    };
+}
+
+pub fn each_implementation_for_type(cdata: cmd,
+                                    id: ast::NodeId,
+                                    callback: &fn(ast::def_id)) {
+    let item_doc = lookup_item(id, cdata.data);
+    do reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl)
+            |impl_doc| {
+        let implementation_def_id = item_def_id(impl_doc, cdata);
+        callback(implementation_def_id);
+        true
+    };
+}
+
+pub fn each_implementation_for_trait(cdata: cmd,
+                                     id: ast::NodeId,
+                                     callback: &fn(ast::def_id)) {
+    let item_doc = lookup_item(id, cdata.data);
+
+    let _ = do reader::tagged_docs(item_doc,
+                                   tag_items_data_item_extension_impl)
+            |impl_doc| {
+        let implementation_def_id = item_def_id(impl_doc, cdata);
+        callback(implementation_def_id);
+        true
+    };
+}
+
+pub fn get_trait_of_method(cdata: cmd, id: ast::NodeId, tcx: ty::ctxt)
+                           -> Option<ast::def_id> {
+    let item_doc = lookup_item(id, cdata.data);
+    let parent_item_id = match item_parent_item(item_doc) {
+        None => return None,
+        Some(item_id) => item_id,
+    };
+    let parent_item_id = translate_def_id(cdata, parent_item_id);
+    let parent_item_doc = lookup_item(parent_item_id.node, cdata.data);
+    match item_family(parent_item_doc) {
+        Trait => Some(item_def_id(parent_item_doc, cdata)),
+        Impl => {
+            do reader::maybe_get_doc(parent_item_doc, tag_item_trait_ref).map
+                    |_| {
+                item_trait_ref(parent_item_doc, tcx, cdata).def_id
+            }
+        }
+        _ => None
+    }
+}
+
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 21eee26620c..790dff2886f 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -39,6 +39,7 @@ use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::span_handler;
 use syntax::parse::token::special_idents;
 use syntax::ast_util;
+use syntax::visit::Visitor;
 use syntax::visit;
 use syntax::parse::token;
 use syntax;
@@ -72,6 +73,7 @@ struct Stats {
     dep_bytes: uint,
     lang_item_bytes: uint,
     link_args_bytes: uint,
+    impl_bytes: uint,
     misc_bytes: uint,
     item_bytes: uint,
     index_bytes: uint,
@@ -511,8 +513,12 @@ fn encode_reexports(ecx: &EncodeContext,
         Some(ref exports) => {
             debug!("(encoding info for module) found reexports for %d", id);
             for exp in exports.iter() {
-                debug!("(encoding info for module) reexport '%s' for %d",
-                       exp.name, id);
+                debug!("(encoding info for module) reexport '%s' (%d/%d) for \
+                        %d",
+                       exp.name,
+                       exp.def_id.crate,
+                       exp.def_id.node,
+                       id);
                 ebml_w.start_tag(tag_items_data_item_reexport);
                 ebml_w.start_tag(tag_items_data_item_reexport_def_id);
                 ebml_w.wr_str(def_to_str(exp.def_id));
@@ -635,15 +641,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic
     fn encode_mutability(ebml_w: &writer::Encoder,
                          m: ast::mutability) {
         match m {
-            m_imm => {
-                ebml_w.writer.write(&[ 'i' as u8 ]);
-            }
-            m_mutbl => {
-                ebml_w.writer.write(&[ 'm' as u8 ]);
-            }
-            m_const => {
-                ebml_w.writer.write(&[ 'c' as u8 ]);
-            }
+            m_imm => ebml_w.writer.write(&[ 'i' as u8 ]),
+            m_mutbl => ebml_w.writer.write(&[ 'm' as u8 ]),
         }
     }
 }
@@ -804,6 +803,38 @@ fn should_inline(attrs: &[Attribute]) -> bool {
     }
 }
 
+// Encodes the inherent implementations of a structure, enumeration, or trait.
+fn encode_inherent_implementations(ecx: &EncodeContext,
+                                   ebml_w: &mut writer::Encoder,
+                                   def_id: def_id) {
+    match ecx.tcx.inherent_impls.find(&def_id) {
+        None => {}
+        Some(&implementations) => {
+            for implementation in implementations.iter() {
+                ebml_w.start_tag(tag_items_data_item_inherent_impl);
+                encode_def_id(ebml_w, implementation.did);
+                ebml_w.end_tag();
+            }
+        }
+    }
+}
+
+// Encodes the implementations of a trait defined in this crate.
+fn encode_extension_implementations(ecx: &EncodeContext,
+                                    ebml_w: &mut writer::Encoder,
+                                    trait_def_id: def_id) {
+    match ecx.tcx.trait_impls.find(&trait_def_id) {
+        None => {}
+        Some(&implementations) => {
+            for implementation in implementations.iter() {
+                ebml_w.start_tag(tag_items_data_item_extension_impl);
+                encode_def_id(ebml_w, implementation.did);
+                ebml_w.end_tag();
+            }
+        }
+    }
+}
+
 fn encode_info_for_item(ecx: &EncodeContext,
                         ebml_w: &mut writer::Encoder,
                         item: @item,
@@ -907,6 +938,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
         (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
         encode_region_param(ecx, ebml_w, item);
+
+        // Encode inherent implementations for this enumeration.
+        encode_inherent_implementations(ecx, ebml_w, def_id);
+
         ebml_w.end_tag();
 
         encode_enum_variant_info(ecx,
@@ -959,6 +994,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
             }
         }
 
+        // Encode inherent implementations for this structure.
+        encode_inherent_implementations(ecx, ebml_w, def_id);
+
         /* Each class has its own index -- encode it */
         let bkts = create_index(idx);
         encode_index(ebml_w, bkts, write_i64);
@@ -995,7 +1033,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_name(ecx, ebml_w, item.ident);
         encode_attributes(ebml_w, item.attrs);
         match ty.node {
-            ast::ty_path(ref path, ref bounds, _) if path.idents.len() == 1 => {
+            ast::ty_path(ref path, ref bounds, _) if path.segments
+                                                         .len() == 1 => {
                 assert!(bounds.is_none());
                 encode_impl_type_basename(ecx, ebml_w,
                                           ast_util::path_to_ident(path));
@@ -1073,6 +1112,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
             let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
             encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
         }
+
+        // Encode the implementations of this trait.
+        encode_extension_implementations(ecx, ebml_w, def_id);
+
         ebml_w.end_tag();
 
         // Now output the method info for each method.
@@ -1134,6 +1177,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
             ebml_w.end_tag();
         }
+
+        // Encode inherent implementations for this trait.
+        encode_inherent_implementations(ecx, ebml_w, def_id);
       }
       item_mac(*) => fail!("item macros unimplemented")
     }
@@ -1227,7 +1273,10 @@ struct EncodeVisitor {
 }
 
 impl visit::Visitor<()> for EncodeVisitor {
-    fn visit_expr(&mut self, ex:@expr, _:()) { my_visit_expr(ex); }
+    fn visit_expr(&mut self, ex:@expr, _:()) {
+        visit::walk_expr(self, ex, ());
+        my_visit_expr(ex);
+    }
     fn visit_item(&mut self, i:@item, _:()) {
         visit::walk_item(self, i, ());
         my_visit_item(i,
@@ -1516,6 +1565,60 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
     ebml_w.end_tag();
 }
 
+struct ImplVisitor<'self> {
+    ecx: &'self EncodeContext<'self>,
+    ebml_w: &'self mut writer::Encoder,
+}
+
+impl<'self> Visitor<()> for ImplVisitor<'self> {
+    fn visit_item(&mut self, item: @item, _: ()) {
+        match item.node {
+            item_impl(_, Some(ref trait_ref), _, _) => {
+                let def_map = self.ecx.tcx.def_map;
+                let trait_def = def_map.get_copy(&trait_ref.ref_id);
+                let def_id = ast_util::def_id_of_def(trait_def);
+
+                // Load eagerly if this is an implementation of the Drop trait
+                // or if the trait is not defined in this crate.
+                if def_id == self.ecx.tcx.lang_items.drop_trait().unwrap() ||
+                        def_id.crate != LOCAL_CRATE {
+                    self.ebml_w.start_tag(tag_impls_impl);
+                    encode_def_id(self.ebml_w, local_def(item.id));
+                    self.ebml_w.end_tag();
+                }
+            }
+            _ => {}
+        }
+        visit::walk_item(self, item, ());
+    }
+}
+
+/// Encodes implementations that are eagerly loaded.
+///
+/// None of this is necessary in theory; we can load all implementations
+/// lazily. However, in two cases the optimizations to lazily load
+/// implementations are not yet implemented. These two cases, which require us
+/// to load implementations eagerly, are:
+///
+/// * Destructors (implementations of the Drop trait).
+///
+/// * Implementations of traits not defined in this crate.
+fn encode_impls(ecx: &EncodeContext,
+                crate: &Crate,
+                ebml_w: &mut writer::Encoder) {
+    ebml_w.start_tag(tag_impls);
+
+    {
+        let mut visitor = ImplVisitor {
+            ecx: ecx,
+            ebml_w: ebml_w,
+        };
+        visit::walk_crate(&mut visitor, crate, ());
+    }
+
+    ebml_w.end_tag();
+}
+
 fn encode_misc_info(ecx: &EncodeContext,
                     crate: &Crate,
                     ebml_w: &mut writer::Encoder) {
@@ -1580,6 +1683,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
         dep_bytes: 0,
         lang_item_bytes: 0,
         link_args_bytes: 0,
+        impl_bytes: 0,
         misc_bytes: 0,
         item_bytes: 0,
         index_bytes: 0,
@@ -1638,6 +1742,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
     encode_link_args(&ecx, &mut ebml_w);
     ecx.stats.link_args_bytes = *wr.pos - i;
 
+    // Encode the def IDs of impls, for coherence checking.
+    i = *wr.pos;
+    encode_impls(&ecx, crate, &mut ebml_w);
+    ecx.stats.impl_bytes = *wr.pos - i;
+
     // Encode miscellaneous info.
     i = *wr.pos;
     encode_misc_info(&ecx, crate, &mut ebml_w);
@@ -1670,6 +1779,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
         printfln!("       dep bytes: %u", ecx.stats.dep_bytes);
         printfln!(" lang item bytes: %u", ecx.stats.lang_item_bytes);
         printfln!(" link args bytes: %u", ecx.stats.link_args_bytes);
+        printfln!("      impl bytes: %u", ecx.stats.impl_bytes);
         printfln!("      misc bytes: %u", ecx.stats.misc_bytes);
         printfln!("      item bytes: %u", ecx.stats.item_bytes);
         printfln!("     index bytes: %u", ecx.stats.index_bytes);
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 89b30e46ac0..f5bad88b1ca 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -138,12 +138,20 @@ fn parse_path(st: &mut PState) -> @ast::Path {
           ':' => { next(st); next(st); }
           c => {
             if c == '(' {
-                return @ast::Path { span: dummy_sp(),
-                                    global: false,
-                                    idents: idents,
-                                    rp: None,
-                                    types: ~[] };
-            } else { idents.push(parse_ident_(st, is_last)); }
+                return @ast::Path {
+                    span: dummy_sp(),
+                    global: false,
+                    segments: idents.move_iter().map(|identifier| {
+                        ast::PathSegment {
+                            identifier: identifier,
+                            lifetime: None,
+                            types: opt_vec::Empty,
+                        }
+                    }).collect()
+                };
+            } else {
+                idents.push(parse_ident_(st, is_last));
+            }
           }
         }
     };
@@ -417,7 +425,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
 fn parse_mutability(st: &mut PState) -> ast::mutability {
     match peek(st) {
       'm' => { next(st); ast::m_mutbl }
-      '?' => { next(st); ast::m_const }
       _ => { ast::m_imm }
     }
 }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 5611808cc6d..d00928dd3db 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -99,7 +99,6 @@ fn enc_mutability(w: @io::Writer, mt: ast::mutability) {
     match mt {
       m_imm => (),
       m_mutbl => w.write_char('m'),
-      m_const => w.write_char('?')
     }
 }
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 857579b5bf0..d6b22381192 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -374,9 +374,16 @@ impl tr for ast::def {
     fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def {
         match *self {
           ast::def_fn(did, p) => ast::def_fn(did.tr(xcx), p),
-          ast::def_static_method(did, did2_opt, p) => {
+          ast::def_static_method(did, wrapped_did2, p) => {
             ast::def_static_method(did.tr(xcx),
-                                   did2_opt.map(|did2| did2.tr(xcx)),
+                                   match wrapped_did2 {
+                                    ast::FromTrait(did2) => {
+                                        ast::FromTrait(did2.tr(xcx))
+                                    }
+                                    ast::FromImpl(did2) => {
+                                        ast::FromImpl(did2.tr(xcx))
+                                    }
+                                   },
                                    p)
           }
           ast::def_method(did0, did1) => {
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index 4991f75dc3e..485a0aefe98 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -23,12 +23,12 @@ use mc = middle::mem_categorization;
 use middle::borrowck::*;
 use middle::moves;
 use middle::ty;
-use syntax::ast::{m_mutbl, m_imm, m_const};
+use syntax::ast::{m_imm, m_mutbl};
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::span;
-use syntax::visit;
 use syntax::visit::Visitor;
+use syntax::visit;
 use util::ppaux::Repr;
 
 #[deriving(Clone)]
@@ -86,6 +86,44 @@ enum MoveError {
 }
 
 impl<'self> CheckLoanCtxt<'self> {
+    fn check_by_move_capture(&self,
+                             closure_id: ast::NodeId,
+                             cap_var: &moves::CaptureVar,
+                             move_path: @LoanPath) {
+        let move_err = self.analyze_move_out_from(closure_id, move_path);
+        match move_err {
+            MoveOk => {}
+            MoveWhileBorrowed(loan_path, loan_span) => {
+                self.bccx.span_err(
+                    cap_var.span,
+                    fmt!("cannot move `%s` into closure \
+                          because it is borrowed",
+                         self.bccx.loan_path_to_str(move_path)));
+                self.bccx.span_note(
+                    loan_span,
+                    fmt!("borrow of `%s` occurs here",
+                         self.bccx.loan_path_to_str(loan_path)));
+            }
+        }
+    }
+
+    fn check_captured_variables(&self, closure_id: ast::NodeId, span: span) {
+        let cap_vars = self.bccx.capture_map.get(&closure_id);
+        for cap_var in cap_vars.iter() {
+            let var_id = ast_util::def_id_of_def(cap_var.def).node;
+            let var_path = @LpVar(var_id);
+            self.check_if_path_is_moved(closure_id, span,
+                                        MovedInCapture, var_path);
+            match cap_var.mode {
+                moves::CapRef | moves::CapCopy => {}
+                moves::CapMove => {
+                    self.check_by_move_capture(closure_id, cap_var, var_path);
+                }
+            }
+        }
+        return;
+    }
+
     pub fn tcx(&self) -> ty::ctxt { self.bccx.tcx }
 
     pub fn each_issued_loan(&self,
@@ -220,9 +258,9 @@ impl<'self> CheckLoanCtxt<'self> {
 
         // Restrictions that would cause the new loan to be illegal:
         let illegal_if = match loan2.mutbl {
-            m_mutbl => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM,
-            m_imm =>   RESTR_ALIAS | RESTR_FREEZE,
-            m_const => RESTR_ALIAS,
+            MutableMutability   => RESTR_ALIAS | RESTR_FREEZE | RESTR_CLAIM,
+            ImmutableMutability => RESTR_ALIAS | RESTR_FREEZE,
+            ConstMutability     => RESTR_ALIAS,
         };
         debug!("illegal_if=%?", illegal_if);
 
@@ -231,7 +269,7 @@ impl<'self> CheckLoanCtxt<'self> {
             if restr.loan_path != loan2.loan_path { loop; }
 
             match (new_loan.mutbl, old_loan.mutbl) {
-                (m_mutbl, m_mutbl) => {
+                (MutableMutability, MutableMutability) => {
                     self.bccx.span_err(
                         new_loan.span,
                         fmt!("cannot borrow `%s` as mutable \
@@ -450,7 +488,6 @@ impl<'self> CheckLoanCtxt<'self> {
                     mc::cat_deref(_, _, mc::unsafe_ptr(*)) |
                     mc::cat_static_item(*) |
                     mc::cat_deref(_, _, mc::gc_ptr(_)) |
-                    mc::cat_deref(_, _, mc::region_ptr(m_const, _)) |
                     mc::cat_deref(_, _, mc::region_ptr(m_imm, _)) => {
                         // Aliasability is independent of base cmt
                         match cmt.freely_aliasable() {
@@ -582,7 +619,6 @@ impl<'self> CheckLoanCtxt<'self> {
                     // Otherwise stop iterating
                     LpExtend(_, mc::McDeclared, _) |
                     LpExtend(_, mc::McImmutable, _) |
-                    LpExtend(_, mc::McReadOnly, _) |
                     LpVar(_) => {
                         return true;
                     }
@@ -590,8 +626,11 @@ impl<'self> CheckLoanCtxt<'self> {
 
                 // Check for a non-const loan of `loan_path`
                 let cont = do this.each_in_scope_loan(expr.id) |loan| {
-                    if loan.loan_path == loan_path && loan.mutbl != m_const {
-                        this.report_illegal_mutation(expr, full_loan_path, loan);
+                    if loan.loan_path == loan_path &&
+                            loan.mutbl != ConstMutability {
+                        this.report_illegal_mutation(expr,
+                                                     full_loan_path,
+                                                     loan);
                         false
                     } else {
                         true
@@ -825,3 +864,4 @@ fn check_loans_in_block<'a>(vt: &mut CheckLoanVisitor,
     visit::walk_block(vt, blk, this);
     this.check_for_conflicting_loans(blk.id);
 }
+
diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
index 1dcfc515139..e76d11c269b 100644
--- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs
+++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
@@ -15,7 +15,7 @@
 use middle::borrowck::*;
 use mc = middle::mem_categorization;
 use middle::ty;
-use syntax::ast::{m_const, m_imm, m_mutbl};
+use syntax::ast::{m_imm, m_mutbl};
 use syntax::ast;
 use syntax::codemap::span;
 use util::ppaux::{note_and_explain_region};
@@ -26,7 +26,7 @@ pub fn guarantee_lifetime(bccx: @BorrowckCtxt,
                           span: span,
                           cmt: mc::cmt,
                           loan_region: ty::Region,
-                          loan_mutbl: ast::mutability) {
+                          loan_mutbl: LoanMutability) {
     debug!("guarantee_lifetime(cmt=%s, loan_region=%s)",
            cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
     let ctxt = GuaranteeLifetimeContext {bccx: bccx,
@@ -54,7 +54,7 @@ struct GuaranteeLifetimeContext {
 
     span: span,
     loan_region: ty::Region,
-    loan_mutbl: ast::mutability,
+    loan_mutbl: LoanMutability,
     cmt_original: mc::cmt
 }
 
@@ -235,11 +235,11 @@ impl GuaranteeLifetimeContext {
         // we need to dynamically mark it to prevent incompatible
         // borrows from happening later.
         let opt_dyna = match ptr_mutbl {
-            m_imm | m_const => None,
+            m_imm => None,
             m_mutbl => {
                 match self.loan_mutbl {
-                    m_mutbl => Some(DynaMut),
-                    m_imm | m_const => Some(DynaImm)
+                    MutableMutability => Some(DynaMut),
+                    ImmutableMutability | ConstMutability => Some(DynaImm)
                 }
             }
         };
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index 6d2a4fcc9f3..dbe5214e0eb 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -26,7 +26,6 @@ use middle::ty;
 use util::common::indenter;
 use util::ppaux::{Repr};
 
-use syntax::ast::{m_const, m_imm, m_mutbl};
 use syntax::ast;
 use syntax::ast_util::id_range;
 use syntax::codemap::span;
@@ -237,7 +236,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor,
         // make sure that the thing we are pointing out stays valid
         // for the lifetime `scope_r` of the resulting ptr:
         let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex));
-        this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r);
+        this.guarantee_valid(ex.id,
+                             ex.span,
+                             base_cmt,
+                             LoanMutability::from_ast_mutability(mutbl),
+                             scope_r);
         visit::walk_expr(v, ex, this);
       }
 
@@ -278,7 +281,11 @@ fn gather_loans_in_expr(v: &mut GatherLoanVisitor,
           // adjustments).
           let scope_r = ty::re_scope(ex.id);
           let arg_cmt = this.bccx.cat_expr(arg);
-          this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r);
+          this.guarantee_valid(arg.id,
+                               arg.span,
+                               arg_cmt,
+                               ImmutableMutability,
+                               scope_r);
           visit::walk_expr(v, ex, this);
       }
 
@@ -357,18 +364,22 @@ impl GatherLoanCtxt {
 
                 match *autoref {
                     ty::AutoPtr(r, m) => {
+                        let loan_mutability =
+                            LoanMutability::from_ast_mutability(m);
                         self.guarantee_valid(expr.id,
                                              expr.span,
                                              cmt,
-                                             m,
+                                             loan_mutability,
                                              r)
                     }
                     ty::AutoBorrowVec(r, m) | ty::AutoBorrowVecRef(r, m) => {
                         let cmt_index = mcx.cat_index(expr, cmt, autoderefs+1);
+                        let loan_mutability =
+                            LoanMutability::from_ast_mutability(m);
                         self.guarantee_valid(expr.id,
                                              expr.span,
                                              cmt_index,
-                                             m,
+                                             loan_mutability,
                                              r)
                     }
                     ty::AutoBorrowFn(r) => {
@@ -376,15 +387,17 @@ impl GatherLoanCtxt {
                         self.guarantee_valid(expr.id,
                                              expr.span,
                                              cmt_deref,
-                                             m_imm,
+                                             ImmutableMutability,
                                              r)
                     }
                     ty::AutoBorrowObj(r, m) => {
                         let cmt_deref = mcx.cat_deref_fn_or_obj(expr, cmt, 0);
+                        let loan_mutability =
+                            LoanMutability::from_ast_mutability(m);
                         self.guarantee_valid(expr.id,
                                              expr.span,
                                              cmt_deref,
-                                             m,
+                                             loan_mutability,
                                              r)
                     }
                     ty::AutoUnsafe(_) => {}
@@ -402,7 +415,7 @@ impl GatherLoanCtxt {
                            borrow_id: ast::NodeId,
                            borrow_span: span,
                            cmt: mc::cmt,
-                           req_mutbl: ast::mutability,
+                           req_mutbl: LoanMutability,
                            loan_region: ty::Region) {
         debug!("guarantee_valid(borrow_id=%?, cmt=%s, \
                 req_mutbl=%?, loan_region=%?)",
@@ -473,7 +486,7 @@ impl GatherLoanCtxt {
                 let kill_scope = self.compute_kill_scope(loan_scope, loan_path);
                 debug!("kill_scope = %?", kill_scope);
 
-                if req_mutbl == m_mutbl {
+                if req_mutbl == MutableMutability {
                     self.mark_loan_path_as_mutated(loan_path);
                 }
 
@@ -516,7 +529,7 @@ impl GatherLoanCtxt {
             //        index: all_loans.len(),
             //        loan_path: loan_path,
             //        cmt: cmt,
-            //        mutbl: m_const,
+            //        mutbl: ConstMutability,
             //        gen_scope: borrow_id,
             //        kill_scope: kill_scope,
             //        span: borrow_span,
@@ -527,29 +540,20 @@ impl GatherLoanCtxt {
         fn check_mutability(bccx: @BorrowckCtxt,
                             borrow_span: span,
                             cmt: mc::cmt,
-                            req_mutbl: ast::mutability) {
+                            req_mutbl: LoanMutability) {
             //! Implements the M-* rules in doc.rs.
 
             match req_mutbl {
-                m_const => {
+                ConstMutability => {
                     // Data of any mutability can be lent as const.
                 }
 
-                m_imm => {
-                    match cmt.mutbl {
-                        mc::McImmutable | mc::McDeclared | mc::McInherited => {
-                            // both imm and mut data can be lent as imm;
-                            // for mutable data, this is a freeze
-                        }
-                        mc::McReadOnly => {
-                            bccx.report(BckError {span: borrow_span,
-                                                  cmt: cmt,
-                                                  code: err_mutbl(req_mutbl)});
-                        }
-                    }
+                ImmutableMutability => {
+                    // both imm and mut data can be lent as imm;
+                    // for mutable data, this is a freeze
                 }
 
-                m_mutbl => {
+                MutableMutability => {
                     // Only mutable data can be lent as mutable.
                     if !cmt.mutbl.is_mutable() {
                         bccx.report(BckError {span: borrow_span,
@@ -561,12 +565,14 @@ impl GatherLoanCtxt {
         }
     }
 
-    pub fn restriction_set(&self, req_mutbl: ast::mutability)
+    pub fn restriction_set(&self, req_mutbl: LoanMutability)
                            -> RestrictionSet {
         match req_mutbl {
-            m_const => RESTR_EMPTY,
-            m_imm   => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM,
-            m_mutbl => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE
+            ConstMutability => RESTR_EMPTY,
+            ImmutableMutability => RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM,
+            MutableMutability => {
+                RESTR_EMPTY | RESTR_MUTATE | RESTR_CLAIM | RESTR_FREEZE
+            }
         }
     }
 
@@ -582,8 +588,8 @@ impl GatherLoanCtxt {
                 self.mark_loan_path_as_mutated(base);
             }
             LpExtend(_, mc::McDeclared, _) |
-            LpExtend(_, mc::McImmutable, _) |
-            LpExtend(_, mc::McReadOnly, _) => {
+            LpExtend(_, mc::McImmutable, _) => {
+                // Nothing to do.
             }
         }
     }
@@ -701,8 +707,13 @@ impl GatherLoanCtxt {
                             }
                         }
                     };
-                    self.guarantee_valid(pat.id, pat.span,
-                                         cmt_discr, mutbl, scope_r);
+                    let loan_mutability =
+                        LoanMutability::from_ast_mutability(mutbl);
+                    self.guarantee_valid(pat.id,
+                                         pat.span,
+                                         cmt_discr,
+                                         loan_mutability,
+                                         scope_r);
                   }
                   ast::bind_infer => {
                       // No borrows here, but there may be moves
@@ -725,6 +736,8 @@ impl GatherLoanCtxt {
                       self.vec_slice_info(slice_pat, slice_ty);
                   let mcx = self.bccx.mc_ctxt();
                   let cmt_index = mcx.cat_index(slice_pat, cmt, 0);
+                  let slice_loan_mutability =
+                    LoanMutability::from_ast_mutability(slice_mutbl);
 
                   // Note: We declare here that the borrow occurs upon
                   // entering the `[...]` pattern. This implies that
@@ -743,8 +756,11 @@ impl GatherLoanCtxt {
                   // trans do the right thing, and it would only work
                   // for `~` vectors. It seems simpler to just require
                   // that people call `vec.pop()` or `vec.unshift()`.
-                  self.guarantee_valid(pat.id, pat.span,
-                                       cmt_index, slice_mutbl, slice_r);
+                  self.guarantee_valid(pat.id,
+                                       pat.span,
+                                       cmt_index,
+                                       slice_loan_mutability,
+                                       slice_r);
               }
 
               _ => {}
diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
index ccfef63d9bc..26c2cff189c 100644
--- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs
+++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
@@ -15,7 +15,7 @@ use std::vec;
 use middle::borrowck::*;
 use mc = middle::mem_categorization;
 use middle::ty;
-use syntax::ast::{m_const, m_imm, m_mutbl};
+use syntax::ast::{m_imm, m_mutbl};
 use syntax::codemap::span;
 
 pub enum RestrictionResult {
@@ -121,13 +121,6 @@ impl RestrictionsContext {
                 Safe
             }
 
-            mc::cat_deref(_, _, mc::region_ptr(m_const, _)) |
-            mc::cat_deref(_, _, mc::gc_ptr(m_const)) => {
-                // R-Deref-Freeze-Borrowed
-                self.check_no_mutability_control(cmt, restrictions);
-                Safe
-            }
-
             mc::cat_deref(cmt_base, _, pk @ mc::gc_ptr(m_mutbl)) => {
                 // R-Deref-Managed-Borrowed
                 //
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 4490fe65d91..7113af3fbc2 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -241,12 +241,39 @@ pub enum PartialTotal {
 ///////////////////////////////////////////////////////////////////////////
 // Loans and loan paths
 
+#[deriving(Clone, Eq)]
+pub enum LoanMutability {
+    ImmutableMutability,
+    ConstMutability,
+    MutableMutability,
+}
+
+impl LoanMutability {
+    pub fn from_ast_mutability(ast_mutability: ast::mutability)
+                               -> LoanMutability {
+        match ast_mutability {
+            ast::m_imm => ImmutableMutability,
+            ast::m_mutbl => MutableMutability,
+        }
+    }
+}
+
+impl ToStr for LoanMutability {
+    fn to_str(&self) -> ~str {
+        match *self {
+            ImmutableMutability => ~"immutable",
+            ConstMutability => ~"read-only",
+            MutableMutability => ~"mutable",
+        }
+    }
+}
+
 /// Record of a loan that was issued.
 pub struct Loan {
     index: uint,
     loan_path: @LoanPath,
     cmt: mc::cmt,
-    mutbl: ast::mutability,
+    mutbl: LoanMutability,
     restrictions: ~[Restriction],
     gen_scope: ast::NodeId,
     kill_scope: ast::NodeId,
@@ -417,7 +444,7 @@ impl ToStr for DynaFreezeKind {
 // Errors that can occur
 #[deriving(Eq)]
 pub enum bckerr_code {
-    err_mutbl(ast::mutability),
+    err_mutbl(LoanMutability),
     err_out_of_root_scope(ty::Region, ty::Region), // superscope, subscope
     err_out_of_scope(ty::Region, ty::Region), // superscope, subscope
     err_freeze_aliasable_const
@@ -794,17 +821,14 @@ impl BorrowckCtxt {
         mc.cmt_to_str(cmt)
     }
 
-    pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str {
-        let mc = &mc::mem_categorization_ctxt {tcx: self.tcx,
-                                               method_map: self.method_map};
-        mc.mut_to_str(mutbl)
+    pub fn mut_to_str(&self, mutbl: LoanMutability) -> ~str {
+        mutbl.to_str()
     }
 
     pub fn mut_to_keyword(&self, mutbl: ast::mutability) -> &'static str {
         match mutbl {
             ast::m_imm => "",
-            ast::m_const => "const",
-            ast::m_mutbl => "mut"
+            ast::m_mutbl => "mut",
         }
     }
 }
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 0530ffd30b4..fc779f73060 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -141,7 +141,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
             // to handle on-demand instantiation of functions via
             // foo::<bar> in a const. Currently that is only done on
             // a path in trans::callee that only works in block contexts.
-            if pth.types.len() != 0 {
+            if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
                 sess.span_err(
                     e.span, "paths in constants may only refer to \
                              items without type parameters");
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 8be9a5db8bb..3f1e409e170 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -52,7 +52,7 @@ use middle::typeck;
 use util::ppaux::{ty_to_str, region_ptr_to_str, Repr};
 use util::common::indenter;
 
-use syntax::ast::{m_imm, m_const, m_mutbl};
+use syntax::ast::{m_imm, m_mutbl};
 use syntax::ast;
 use syntax::codemap::span;
 use syntax::print::pprust;
@@ -113,7 +113,6 @@ pub enum ElementKind {
 #[deriving(Eq, IterBytes)]
 pub enum MutabilityCategory {
     McImmutable, // Immutable.
-    McReadOnly,  // Read-only (`const`)
     McDeclared,  // Directly declared as mutable.
     McInherited  // Inherited from the fact that owner is mutable.
 }
@@ -297,7 +296,6 @@ impl MutabilityCategory {
     pub fn from_mutbl(m: ast::mutability) -> MutabilityCategory {
         match m {
             m_imm => McImmutable,
-            m_const => McReadOnly,
             m_mutbl => McDeclared
         }
     }
@@ -305,7 +303,6 @@ impl MutabilityCategory {
     pub fn inherit(&self) -> MutabilityCategory {
         match *self {
             McImmutable => McImmutable,
-            McReadOnly => McReadOnly,
             McDeclared => McInherited,
             McInherited => McInherited
         }
@@ -313,7 +310,7 @@ impl MutabilityCategory {
 
     pub fn is_mutable(&self) -> bool {
         match *self {
-            McImmutable | McReadOnly => false,
+            McImmutable => false,
             McDeclared | McInherited => true
         }
     }
@@ -321,7 +318,7 @@ impl MutabilityCategory {
     pub fn is_immutable(&self) -> bool {
         match *self {
             McImmutable => true,
-            McReadOnly | McDeclared | McInherited => false
+            McDeclared | McInherited => false
         }
     }
 
@@ -329,7 +326,6 @@ impl MutabilityCategory {
         match *self {
             McDeclared | McInherited => "mutable",
             McImmutable => "immutable",
-            McReadOnly => "const"
         }
     }
 }
@@ -610,7 +606,6 @@ impl mem_categorization_ctxt {
                                 -> MutabilityCategory {
         match interior_m {
             m_imm => base_m.inherit(),
-            m_const => McReadOnly,
             m_mutbl => McDeclared
         }
     }
@@ -999,7 +994,6 @@ impl mem_categorization_ctxt {
     pub fn mut_to_str(&self, mutbl: ast::mutability) -> ~str {
         match mutbl {
           m_mutbl => ~"mutable",
-          m_const => ~"const",
           m_imm => ~"immutable"
         }
     }
@@ -1164,7 +1158,6 @@ impl cmt_ {
                 Some(AliasableManaged(m))
             }
 
-            cat_deref(_, _, region_ptr(m @ m_const, _)) |
             cat_deref(_, _, region_ptr(m @ m_imm, _)) => {
                 Some(AliasableBorrowed(m))
             }
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 222bef641d2..ccb62252e5d 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// A pass that checks to make sure private fields and methods aren't used
-// outside their scopes.
-
+//! A pass that checks to make sure private fields and methods aren't used
+//! outside their scopes.
 
 use metadata::csearch;
 use middle::ty::{ty_struct, ty_enum};
@@ -226,7 +225,7 @@ impl PrivacyVisitor {
 
         if method_id.crate == LOCAL_CRATE {
             let is_private = self.method_is_private(span, method_id.node);
-            let container_id = ty::method(self.tcx, method_id).container_id;
+            let container_id = ty::method(self.tcx, method_id).container_id();
             if is_private &&
                     (container_id.crate != LOCAL_CRATE ||
                      !self.privileged_items.iter().any(|x| x == &(container_id.node))) {
@@ -251,7 +250,9 @@ impl PrivacyVisitor {
         match def {
             def_static_method(method_id, _, _) => {
                 debug!("found static method def, checking it");
-                self.check_method_common(span, method_id, path.idents.last())
+                self.check_method_common(span,
+                                         method_id,
+                                         &path.segments.last().identifier)
             }
             def_fn(def_id, _) => {
                 if def_id.crate == LOCAL_CRATE {
@@ -259,13 +260,19 @@ impl PrivacyVisitor {
                             !self.privileged_items.iter().any(|x| x == &def_id.node) {
                         self.tcx.sess.span_err(span,
                                           fmt!("function `%s` is private",
-                                               token::ident_to_str(path.idents.last())));
+                                               token::ident_to_str(
+                                                &path.segments
+                                                     .last()
+                                                     .identifier)));
                     }
                 } else if csearch::get_item_visibility(self.tcx.sess.cstore,
                                                        def_id) != public {
                     self.tcx.sess.span_err(span,
                                       fmt!("function `%s` is private",
-                                           token::ident_to_str(path.idents.last())));
+                                           token::ident_to_str(
+                                                &path.segments
+                                                     .last()
+                                                     .identifier)));
                 }
             }
             _ => {}
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index ddd22a0add4..d6b6a948a57 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -827,7 +827,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
           Some(&ast::def_trait(did)) |
           Some(&ast::def_struct(did)) => {
             if did.crate == ast::LOCAL_CRATE {
-                if cx.region_is_relevant(&path.rp) {
+                if cx.region_is_relevant(&path.segments.last().lifetime) {
                     cx.add_dep(did.node);
                 }
             } else {
@@ -837,7 +837,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
                   Some(variance) => {
                     debug!("reference to external, rp'd type %s",
                            pprust::ty_to_str(ty, sess.intr()));
-                    if cx.region_is_relevant(&path.rp) {
+                    if cx.region_is_relevant(&path.segments.last().lifetime) {
                         let rv = cx.add_variance(variance);
                         cx.add_rp(cx.item_id, rv)
                     }
@@ -860,7 +860,7 @@ fn determine_rp_in_ty(visitor: &mut DetermineRpVisitor,
       ast::ty_path(ref path, _, _) => {
         // type parameters are---for now, anyway---always invariant
         do cx.with_ambient_variance(rv_invariant) {
-            for tp in path.types.iter() {
+            for tp in path.segments.iter().flat_map(|s| s.types.iter()) {
                 visitor.visit_ty(tp, cx);
             }
         }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index d60d1e2b845..2989f104729 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -10,10 +10,11 @@
 
 
 use driver::session::Session;
-use metadata::csearch::{each_path, get_trait_method_def_ids};
+use metadata::csearch::get_trait_method_def_ids;
 use metadata::csearch::get_method_name_and_explicit_self;
 use metadata::csearch::get_static_methods_if_impl;
 use metadata::csearch::{get_type_name_if_impl, get_struct_fields};
+use metadata::csearch;
 use metadata::cstore::find_extern_mod_stmt_cnum;
 use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
 use middle::lang_items::LanguageItems;
@@ -55,6 +56,12 @@ pub type BindingMap = HashMap<ident,binding_info>;
 // Trait method resolution
 pub type TraitMap = HashMap<NodeId,@mut ~[def_id]>;
 
+// A summary of the generics on a trait.
+struct TraitGenerics {
+    has_lifetime: bool,
+    type_parameter_count: uint,
+}
+
 // This is the replacement export map. It maps a module to all of the exports
 // within.
 pub type ExportMap2 = @mut HashMap<NodeId, ~[Export2]>;
@@ -464,12 +471,18 @@ pub struct Module {
 
     // The index of the import we're resolving.
     resolved_import_count: uint,
+
+    // Whether this module is populated. If not populated, any attempt to
+    // access the children must be preceded with a
+    // `populate_module_if_necessary` call.
+    populated: bool,
 }
 
 pub fn Module(parent_link: ParentLink,
               def_id: Option<def_id>,
-              kind: ModuleKind)
-           -> Module {
+              kind: ModuleKind,
+              external: bool)
+              -> Module {
     Module {
         parent_link: parent_link,
         def_id: def_id,
@@ -480,7 +493,8 @@ pub fn Module(parent_link: ParentLink,
         anonymous_children: @mut HashMap::new(),
         import_resolutions: @mut HashMap::new(),
         glob_count: 0,
-        resolved_import_count: 0
+        resolved_import_count: 0,
+        populated: !external,
     }
 }
 
@@ -527,9 +541,10 @@ impl NameBindings {
                          parent_link: ParentLink,
                          def_id: Option<def_id>,
                          kind: ModuleKind,
+                         external: bool,
                          sp: span) {
         // Merges the module with the existing type def or creates a new one.
-        let module_ = @mut Module(parent_link, def_id, kind);
+        let module_ = @mut Module(parent_link, def_id, kind, external);
         match self.type_def {
             None => {
                 self.type_def = Some(TypeNsDef {
@@ -556,10 +571,11 @@ impl NameBindings {
                            parent_link: ParentLink,
                            def_id: Option<def_id>,
                            kind: ModuleKind,
+                           external: bool,
                            _sp: span) {
         match self.type_def {
             None => {
-                let module = @mut Module(parent_link, def_id, kind);
+                let module = @mut Module(parent_link, def_id, kind, external);
                 self.type_def = Some(TypeNsDef {
                     privacy: privacy,
                     module_def: Some(module),
@@ -570,7 +586,10 @@ impl NameBindings {
             Some(type_def) => {
                 match type_def.module_def {
                     None => {
-                        let module = @mut Module(parent_link, def_id, kind);
+                        let module = @mut Module(parent_link,
+                                                 def_id,
+                                                 kind,
+                                                 external);
                         self.type_def = Some(TypeNsDef {
                             privacy: privacy,
                             module_def: Some(module),
@@ -792,6 +811,7 @@ pub fn Resolver(session: Session,
                              NoParentLink,
                              Some(def_id { crate: 0, node: 0 }),
                              NormalModuleKind,
+                             false,
                              crate.span);
 
     let current_module = graph_root.get_module();
@@ -1157,6 +1177,7 @@ impl Resolver {
                                             parent_link,
                                             Some(def_id),
                                             NormalModuleKind,
+                                            false,
                                             sp);
 
                 let new_parent =
@@ -1179,6 +1200,7 @@ impl Resolver {
                                                     parent_link,
                                                     Some(def_id),
                                                     ExternModuleKind,
+                                                    false,
                                                     sp);
 
                         ModuleReducedGraphParent(name_bindings.get_module())
@@ -1277,7 +1299,7 @@ impl Resolver {
                     &Ty {
                         node: ty_path(ref path, _, _),
                         _
-                    } if path.idents.len() == 1 => {
+                    } if path.segments.len() == 1 => {
                         let name = path_to_ident(path);
 
                         let new_parent = match parent.children.find(&name) {
@@ -1303,6 +1325,7 @@ impl Resolver {
                                                             parent_link,
                                                             Some(def_id),
                                                             ImplModuleKind,
+                                                            false,
                                                             sp);
 
                                 ModuleReducedGraphParent(
@@ -1321,9 +1344,12 @@ impl Resolver {
                                                method.span);
                             let def = match method.explicit_self.node {
                                 sty_static => {
-                                    // Static methods become `def_fn`s.
-                                    def_fn(local_def(method.id),
-                                           method.purity)
+                                    // Static methods become
+                                    // `def_static_method`s.
+                                    def_static_method(local_def(method.id),
+                                                      FromImpl(local_def(
+                                                        item.id)),
+                                                      method.purity)
                                 }
                                 _ => {
                                     // Non-static methods become
@@ -1357,6 +1383,7 @@ impl Resolver {
                                             parent_link,
                                             Some(local_def(item.id)),
                                             TraitModuleKind,
+                                            false,
                                             sp);
                 let module_parent = ModuleReducedGraphParent(name_bindings.
                                                              get_module());
@@ -1373,7 +1400,7 @@ impl Resolver {
                         sty_static => {
                             // Static methods become `def_static_method`s.
                             def_static_method(local_def(ty_m.id),
-                                              Some(local_def(item.id)),
+                                              FromTrait(local_def(item.id)),
                                               ty_m.purity)
                         }
                         _ => {
@@ -1476,20 +1503,22 @@ impl Resolver {
                     let mut module_path = ~[];
                     match view_path.node {
                         view_path_simple(_, ref full_path, _) => {
-                            let path_len = full_path.idents.len();
+                            let path_len = full_path.segments.len();
                             assert!(path_len != 0);
 
-                            for (i, ident) in full_path.idents.iter().enumerate() {
+                            for (i, segment) in full_path.segments
+                                                         .iter()
+                                                         .enumerate() {
                                 if i != path_len - 1 {
-                                    module_path.push(*ident);
+                                    module_path.push(segment.identifier)
                                 }
                             }
                         }
 
                         view_path_glob(ref module_ident_path, _) |
                         view_path_list(ref module_ident_path, _, _) => {
-                            for ident in module_ident_path.idents.iter() {
-                                module_path.push(*ident);
+                            for segment in module_ident_path.segments.iter() {
+                                module_path.push(segment.identifier)
                             }
                         }
                     }
@@ -1498,7 +1527,8 @@ impl Resolver {
                     let module_ = self.get_module_from_parent(parent);
                     match view_path.node {
                         view_path_simple(binding, ref full_path, id) => {
-                            let source_ident = *full_path.idents.last();
+                            let source_ident =
+                                full_path.segments.last().identifier;
                             let subclass = @SingleImport(binding,
                                                          source_ident);
                             self.build_import_directive(privacy,
@@ -1543,7 +1573,8 @@ impl Resolver {
                             (self.get_module_from_parent(parent), name);
                         let external_module = @mut Module(parent_link,
                                                           Some(def_id),
-                                                          NormalModuleKind);
+                                                          NormalModuleKind,
+                                                          false);
 
                         parent.external_module_children.insert(
                             name,
@@ -1607,7 +1638,8 @@ impl Resolver {
             let new_module = @mut Module(
                 BlockParentLink(parent_module, block_id),
                 None,
-                AnonymousModuleKind);
+                AnonymousModuleKind,
+                false);
             parent_module.anonymous_children.insert(block_id, new_module);
             new_parent = ModuleReducedGraphParent(new_module);
         } else {
@@ -1617,23 +1649,22 @@ impl Resolver {
         visit::walk_block(visitor, block, new_parent);
     }
 
-    pub fn handle_external_def(@mut self,
-                               def: def,
-                               visibility: ast::visibility,
-                               modules: &mut HashMap<def_id, @mut Module>,
-                               child_name_bindings: @mut NameBindings,
-                               final_ident: &str,
-                               ident: ident,
-                               new_parent: ReducedGraphParent) {
+    fn handle_external_def(@mut self,
+                           def: def,
+                           visibility: ast::visibility,
+                           child_name_bindings: @mut NameBindings,
+                           final_ident: &str,
+                           ident: ident,
+                           new_parent: ReducedGraphParent) {
         let privacy = visibility_to_privacy(visibility);
         match def {
-          def_mod(def_id) | def_foreign_mod(def_id) => {
+          def_mod(def_id) | def_foreign_mod(def_id) | def_struct(def_id) |
+          def_ty(def_id) => {
             match child_name_bindings.type_def {
               Some(TypeNsDef { module_def: Some(module_def), _ }) => {
                 debug!("(building reduced graph for external crate) \
                         already created module");
                 module_def.def_id = Some(def_id);
-                modules.insert(def_id, module_def);
               }
               Some(_) | None => {
                 debug!("(building reduced graph for \
@@ -1641,45 +1672,20 @@ impl Resolver {
                         %s", final_ident);
                 let parent_link = self.get_parent_link(new_parent, ident);
 
-                // FIXME (#5074): this should be a match on find
-                if !modules.contains_key(&def_id) {
-                    child_name_bindings.define_module(privacy,
-                                                      parent_link,
-                                                      Some(def_id),
-                                                      NormalModuleKind,
-                                                      dummy_sp());
-                    modules.insert(def_id,
-                                   child_name_bindings.get_module());
-                } else {
-                    let existing_module = *modules.get(&def_id);
-
-                    // Create an import resolution to avoid creating cycles in
-                    // the module graph.
-
-                    let resolution = @mut ImportResolution(Public, 0);
-                    resolution.outstanding_references = 0;
-
-                    match existing_module.parent_link {
-                      NoParentLink |
-                      BlockParentLink(*) => {
-                        fail!("can't happen");
-                      }
-                      ModuleParentLink(parent_module, ident) => {
-                        let name_bindings = parent_module.children.get(
-                            &ident);
-                        resolution.type_target =
-                            Some(Target(parent_module, *name_bindings));
-                      }
-                    }
-
-                    debug!("(building reduced graph for external crate) \
-                            ... creating import resolution");
-
-                    new_parent.import_resolutions.insert(ident, resolution);
-                }
+                child_name_bindings.define_module(privacy,
+                                                  parent_link,
+                                                  Some(def_id),
+                                                  NormalModuleKind,
+                                                  true,
+                                                  dummy_sp());
               }
             }
           }
+          _ => {}
+        }
+
+        match def {
+          def_mod(_) | def_foreign_mod(_) => {}
           def_variant(*) => {
             debug!("(building reduced graph for external crate) building \
                     variant %s",
@@ -1691,7 +1697,7 @@ impl Resolver {
           }
           def_fn(*) | def_static_method(*) | def_static(*) => {
             debug!("(building reduced graph for external \
-                    crate) building value %s", final_ident);
+                    crate) building value (fn/static) %s", final_ident);
             child_name_bindings.define_value(privacy, def, dummy_sp());
           }
           def_trait(def_id) => {
@@ -1737,6 +1743,7 @@ impl Resolver {
                                                   parent_link,
                                                   Some(def_id),
                                                   TraitModuleKind,
+                                                  true,
                                                   dummy_sp())
           }
           def_ty(_) => {
@@ -1767,184 +1774,183 @@ impl Resolver {
         }
     }
 
-    /**
-     * Builds the reduced graph rooted at the 'use' directive for an external
-     * crate.
-     */
-    pub fn build_reduced_graph_for_external_crate(@mut self,
-                                                  root: @mut Module) {
-        let mut modules = HashMap::new();
-
-        // Create all the items reachable by paths.
-        do each_path(self.session.cstore, root.def_id.unwrap().crate)
-                |path_string, def_like, visibility| {
-
-            debug!("(building reduced graph for external crate) found path \
-                        entry: %s (%?)",
-                    path_string, def_like);
-
-            let mut pieces: ~[&str] = path_string.split_str_iter("::").collect();
-            let final_ident_str = pieces.pop();
-            let final_ident = self.session.ident_of(final_ident_str);
-
-            // Find the module we need, creating modules along the way if we
-            // need to.
-
-            let mut current_module = root;
-            for ident_str in pieces.iter() {
-                let ident = self.session.ident_of(*ident_str);
-                // Create or reuse a graph node for the child.
-                let (child_name_bindings, new_parent) =
-                    self.add_child(ident,
-                                   ModuleReducedGraphParent(current_module),
-                                   OverwriteDuplicates,
-                                   dummy_sp());
-
-                // Define or reuse the module node.
-                match child_name_bindings.type_def {
-                    None => {
-                        debug!("(building reduced graph for external crate) \
-                                autovivifying missing type def %s",
-                                *ident_str);
-                        let parent_link = self.get_parent_link(new_parent,
-                                                               ident);
-                        child_name_bindings.define_module(Public,
-                                                          parent_link,
-                                                          None,
-                                                          NormalModuleKind,
-                                                          dummy_sp());
+    /// Builds the reduced graph for a single item in an external crate.
+    fn build_reduced_graph_for_external_crate_def(@mut self,
+                                                  root: @mut Module,
+                                                  def_like: def_like,
+                                                  ident: ident) {
+        match def_like {
+            dl_def(def) => {
+                // Add the new child item, if necessary.
+                match def {
+                    def_foreign_mod(def_id) => {
+                        // Foreign modules have no names. Recur and populate
+                        // eagerly.
+                        do csearch::each_child_of_item(self.session.cstore,
+                                                       def_id)
+                                |def_like, child_ident| {
+                            self.build_reduced_graph_for_external_crate_def(
+                                root,
+                                def_like,
+                                child_ident)
+                        }
                     }
-                    Some(type_ns_def)
-                            if type_ns_def.module_def.is_none() => {
-                        debug!("(building reduced graph for external crate) \
-                                autovivifying missing module def %s",
-                                *ident_str);
-                        let parent_link = self.get_parent_link(new_parent,
-                                                               ident);
-                        child_name_bindings.define_module(Public,
-                                                          parent_link,
-                                                          None,
-                                                          NormalModuleKind,
-                                                          dummy_sp());
+                    _ => {
+                        let (child_name_bindings, new_parent) =
+                            self.add_child(ident,
+                                           ModuleReducedGraphParent(root),
+                                           OverwriteDuplicates,
+                                           dummy_sp());
+
+                        self.handle_external_def(def,
+                                                 public,
+                                                 child_name_bindings,
+                                                 self.session.str_of(ident),
+                                                 ident,
+                                                 new_parent);
                     }
-                    _ => {} // Fall through.
-                }
-
-                current_module = child_name_bindings.get_module();
-            }
-
-            match def_like {
-                dl_def(def) => {
-                    // Add the new child item.
-                    let (child_name_bindings, new_parent) =
-                        self.add_child(final_ident,
-                                       ModuleReducedGraphParent(
-                                            current_module),
-                                       OverwriteDuplicates,
-                                       dummy_sp());
-
-                    self.handle_external_def(def,
-                                             visibility,
-                                             &mut modules,
-                                             child_name_bindings,
-                                             self.session.str_of(
-                                                 final_ident),
-                                             final_ident,
-                                             new_parent);
-                }
-                dl_impl(def) => {
-                    // We only process static methods of impls here.
-                    match get_type_name_if_impl(self.session.cstore, def) {
-                        None => {}
-                        Some(final_ident) => {
-                            let static_methods_opt =
-                                get_static_methods_if_impl(
-                                    self.session.cstore, def);
-                            match static_methods_opt {
-                                Some(ref static_methods) if
-                                    static_methods.len() >= 1 => {
-                                    debug!("(building reduced graph for \
-                                            external crate) processing \
-                                            static methods for type name %s",
-                                            self.session.str_of(
-                                                final_ident));
-
-                                    let (child_name_bindings, new_parent) =
-                                        self.add_child(final_ident,
-                                            ModuleReducedGraphParent(
-                                                            current_module),
-                                            OverwriteDuplicates,
-                                            dummy_sp());
-
-                                    // Process the static methods. First,
-                                    // create the module.
-                                    let type_module;
-                                    match child_name_bindings.type_def {
-                                        Some(TypeNsDef {
-                                            module_def: Some(module_def),
-                                            _
-                                        }) => {
-                                            // We already have a module. This
-                                            // is OK.
-                                            type_module = module_def;
-
-                                            // Mark it as an impl module if
-                                            // necessary.
-                                            type_module.kind = ImplModuleKind;
-                                        }
-                                        Some(_) | None => {
-                                            let parent_link =
-                                                self.get_parent_link(
-                                                    new_parent, final_ident);
-                                            child_name_bindings.define_module(
-                                                Public,
-                                                parent_link,
-                                                Some(def),
-                                                ImplModuleKind,
-                                                dummy_sp());
-                                            type_module =
-                                                child_name_bindings.
-                                                    get_module();
-                                        }
+                }
+            }
+            dl_impl(def) => {
+                // We only process static methods of impls here.
+                match get_type_name_if_impl(self.session.cstore, def) {
+                    None => {}
+                    Some(final_ident) => {
+                        let static_methods_opt =
+                            get_static_methods_if_impl(self.session.cstore,
+                                                       def);
+                        match static_methods_opt {
+                            Some(ref static_methods) if
+                                static_methods.len() >= 1 => {
+                                debug!("(building reduced graph for \
+                                        external crate) processing \
+                                        static methods for type name %s",
+                                        self.session.str_of(
+                                            final_ident));
+
+                                let (child_name_bindings, new_parent) =
+                                    self.add_child(
+                                        final_ident,
+                                        ModuleReducedGraphParent(root),
+                                        OverwriteDuplicates,
+                                        dummy_sp());
+
+                                // Process the static methods. First,
+                                // create the module.
+                                let type_module;
+                                match child_name_bindings.type_def {
+                                    Some(TypeNsDef {
+                                        module_def: Some(module_def),
+                                        _
+                                    }) => {
+                                        // We already have a module. This
+                                        // is OK.
+                                        type_module = module_def;
+
+                                        // Mark it as an impl module if
+                                        // necessary.
+                                        type_module.kind = ImplModuleKind;
                                     }
-
-                                    // Add each static method to the module.
-                                    let new_parent = ModuleReducedGraphParent(
-                                        type_module);
-                                    for static_method_info in static_methods.iter() {
-                                        let ident = static_method_info.ident;
-                                        debug!("(building reduced graph for \
-                                                 external crate) creating \
-                                                 static method '%s'",
-                                               self.session.str_of(ident));
-
-                                        let (method_name_bindings, _) =
-                                            self.add_child(
-                                                ident,
-                                                new_parent,
-                                                OverwriteDuplicates,
-                                                dummy_sp());
-                                        let def = def_fn(
-                                            static_method_info.def_id,
-                                            static_method_info.purity);
-                                        method_name_bindings.define_value(
-                                            Public, def, dummy_sp());
+                                    Some(_) | None => {
+                                        let parent_link =
+                                            self.get_parent_link(new_parent,
+                                                                 final_ident);
+                                        child_name_bindings.define_module(
+                                            Public,
+                                            parent_link,
+                                            Some(def),
+                                            ImplModuleKind,
+                                            true,
+                                            dummy_sp());
+                                        type_module =
+                                            child_name_bindings.
+                                                get_module();
                                     }
                                 }
 
-                                // Otherwise, do nothing.
-                                Some(_) | None => {}
+                                // Add each static method to the module.
+                                let new_parent =
+                                    ModuleReducedGraphParent(type_module);
+                                for static_method_info in
+                                        static_methods.iter() {
+                                    let ident = static_method_info.ident;
+                                    debug!("(building reduced graph for \
+                                             external crate) creating \
+                                             static method '%s'",
+                                           self.session.str_of(ident));
+
+                                    let (method_name_bindings, _) =
+                                        self.add_child(ident,
+                                                       new_parent,
+                                                       OverwriteDuplicates,
+                                                       dummy_sp());
+                                    let def = def_fn(
+                                        static_method_info.def_id,
+                                        static_method_info.purity);
+                                    method_name_bindings.define_value(
+                                        Public,
+                                        def,
+                                        dummy_sp());
+                                }
                             }
+
+                            // Otherwise, do nothing.
+                            Some(_) | None => {}
                         }
                     }
                 }
-                dl_field => {
-                    debug!("(building reduced graph for external crate) \
-                            ignoring field");
-                }
             }
-            true
+            dl_field => {
+                debug!("(building reduced graph for external crate) \
+                        ignoring field");
+            }
+        }
+    }
+
+    /// Builds the reduced graph rooted at the given external module.
+    fn populate_external_module(@mut self, module: @mut Module) {
+        debug!("(populating external module) attempting to populate %s",
+               self.module_to_str(module));
+
+        let def_id = match module.def_id {
+            None => {
+                debug!("(populating external module) ... no def ID!");
+                return
+            }
+            Some(def_id) => def_id,
         };
+
+        do csearch::each_child_of_item(self.session.cstore, def_id)
+                |def_like, child_ident| {
+            debug!("(populating external module) ... found ident: %s",
+                   token::ident_to_str(&child_ident));
+            self.build_reduced_graph_for_external_crate_def(module,
+                                                            def_like,
+                                                            child_ident)
+        }
+        module.populated = true
+    }
+
+    /// Ensures that the reduced graph rooted at the given external module
+    /// is built, building it if it is not.
+    fn populate_module_if_necessary(@mut self, module: @mut Module) {
+        if !module.populated {
+            self.populate_external_module(module)
+        }
+        assert!(module.populated)
+    }
+
+    /// Builds the reduced graph rooted at the 'use' directive for an external
+    /// crate.
+    pub fn build_reduced_graph_for_external_crate(@mut self,
+                                                  root: @mut Module) {
+        do csearch::each_top_level_item_of_crate(self.session.cstore,
+                                                 root.def_id.unwrap().crate)
+                |def_like, ident| {
+            self.build_reduced_graph_for_external_crate_def(root,
+                                                            def_like,
+                                                            ident)
+        }
     }
 
     /// Creates and adds an import directive to the given module.
@@ -2043,6 +2049,7 @@ impl Resolver {
                self.module_to_str(module_));
         self.resolve_imports_for_module(module_);
 
+        self.populate_module_if_necessary(module_);
         for (_, &child_node) in module_.children.iter() {
             match child_node.get_module_if_available() {
                 None => {
@@ -2109,6 +2116,14 @@ impl Resolver {
         return result;
     }
 
+    fn path_idents_to_str(@mut self, path: &Path) -> ~str {
+        let identifiers: ~[ast::ident] = path.segments
+                                             .iter()
+                                             .map(|seg| seg.identifier)
+                                             .collect();
+        self.idents_to_str(identifiers)
+    }
+
     pub fn import_directive_subclass_to_str(@mut self,
                                             subclass: ImportDirectiveSubclass)
                                             -> @str {
@@ -2260,6 +2275,7 @@ impl Resolver {
         let mut type_result = UnknownResult;
 
         // Search for direct children of the containing module.
+        self.populate_module_if_necessary(containing_module);
         match containing_module.children.find(&source) {
             None => {
                 // Continue.
@@ -2578,6 +2594,7 @@ impl Resolver {
         };
 
         // Add all children from the containing module.
+        self.populate_module_if_necessary(containing_module);
         for (&ident, name_bindings) in containing_module.children.iter() {
             merge_import_resolution(ident, *name_bindings);
         }
@@ -2811,6 +2828,7 @@ impl Resolver {
 
         // The current module node is handled specially. First, check for
         // its immediate children.
+        self.populate_module_if_necessary(module_);
         match module_.children.find(&name) {
             Some(name_bindings)
                     if name_bindings.defined_in_namespace(namespace) => {
@@ -3065,6 +3083,7 @@ impl Resolver {
                self.module_to_str(module_));
 
         // First, check the direct children of the module.
+        self.populate_module_if_necessary(module_);
         match module_.children.find(&name) {
             Some(name_bindings)
                     if name_bindings.defined_in_namespace(namespace) => {
@@ -3154,6 +3173,7 @@ impl Resolver {
         }
 
         // Descend into children and anonymous children.
+        self.populate_module_if_necessary(module_);
         for (_, &child_node) in module_.children.iter() {
             match child_node.get_module_if_available() {
                 None => {
@@ -3212,6 +3232,7 @@ impl Resolver {
         }
 
         self.record_exports_for_module(module_);
+        self.populate_module_if_necessary(module_);
 
         for (_, &child_name_bindings) in module_.children.iter() {
             match child_name_bindings.get_module_if_available() {
@@ -3325,6 +3346,7 @@ impl Resolver {
                 // Nothing to do.
             }
             Some(name) => {
+                self.populate_module_if_necessary(orig_module);
                 match orig_module.children.find(&name) {
                     None => {
                         debug!("!!! (with scope) didn't find `%s` in `%s`",
@@ -3841,8 +3863,7 @@ impl Resolver {
                                    reference_type: TraitReferenceType) {
         match self.resolve_path(id, &trait_reference.path, TypeNS, true, visitor) {
             None => {
-                let path_str = self.idents_to_str(trait_reference.path.idents);
-
+                let path_str = self.path_idents_to_str(&trait_reference.path);
                 let usage_str = match reference_type {
                     TraitBoundingTypeParameter => "bound type parameter with",
                     TraitImplementation        => "implement",
@@ -3864,7 +3885,7 @@ impl Resolver {
                           generics: &Generics,
                           fields: &[@struct_field],
                           visitor: &mut ResolveVisitor) {
-        let mut ident_map = HashMap::new::<ast::ident, @struct_field>();
+        let mut ident_map: HashMap<ast::ident,@struct_field> = HashMap::new();
         for &field in fields.iter() {
             match field.node.kind {
                 named_field(ident, _) => {
@@ -4141,8 +4162,8 @@ impl Resolver {
                 let mut result_def = None;
 
                 // First, check to see whether the name is a primitive type.
-                if path.idents.len() == 1 {
-                    let name = *path.idents.last();
+                if path.segments.len() == 1 {
+                    let name = path.segments.last().identifier;
 
                     match self.primitive_type_table
                             .primitive_types
@@ -4151,6 +4172,22 @@ impl Resolver {
                         Some(&primitive_type) => {
                             result_def =
                                 Some(def_prim_ty(primitive_type));
+
+                            if path.segments
+                                   .iter()
+                                   .any(|s| s.lifetime.is_some()) {
+                                self.session.span_err(path.span,
+                                                      "lifetime parameters \
+                                                       are not allowed on \
+                                                       this type")
+                            } else if path.segments
+                                          .iter()
+                                          .any(|s| s.types.len() > 0) {
+                                self.session.span_err(path.span,
+                                                      "type parameters are \
+                                                       not allowed on this \
+                                                       type")
+                            }
                         }
                         None => {
                             // Continue.
@@ -4160,12 +4197,17 @@ impl Resolver {
 
                 match result_def {
                     None => {
-                        match self.resolve_path(ty.id, path, TypeNS, true, visitor) {
+                        match self.resolve_path(ty.id,
+                                                path,
+                                                TypeNS,
+                                                true,
+                                                visitor) {
                             Some(def) => {
                                 debug!("(resolving type) resolved `%s` to \
                                         type %?",
-                                       self.session.str_of(
-                                            *path.idents.last()),
+                                       self.session.str_of(path.segments
+                                                               .last()
+                                                               .identifier),
                                        def);
                                 result_def = Some(def);
                             }
@@ -4174,9 +4216,7 @@ impl Resolver {
                             }
                         }
                     }
-                    Some(_) => {
-                        // Continue.
-                    }
+                    Some(_) => {}   // Continue.
                 }
 
                 match result_def {
@@ -4184,14 +4224,15 @@ impl Resolver {
                         // Write the result into the def map.
                         debug!("(resolving type) writing resolution for `%s` \
                                 (id %d)",
-                               self.idents_to_str(path.idents),
+                               self.path_idents_to_str(path),
                                path_id);
                         self.record_def(path_id, def);
                     }
                     None => {
                         self.resolve_error
-                            (ty.span, fmt!("use of undeclared type name `%s`",
-                                           self.idents_to_str(path.idents)));
+                            (ty.span,
+                             fmt!("use of undeclared type name `%s`",
+                                  self.path_idents_to_str(path)))
                     }
                 }
 
@@ -4230,7 +4271,7 @@ impl Resolver {
         do walk_pat(pattern) |pattern| {
             match pattern.node {
                 pat_ident(binding_mode, ref path, _)
-                        if !path.global && path.idents.len() == 1 => {
+                        if !path.global && path.segments.len() == 1 => {
 
                     // The meaning of pat_ident with no type parameters
                     // depends on whether an enum variant or unit-like struct
@@ -4241,7 +4282,7 @@ impl Resolver {
                     // such a value is simply disallowed (since it's rarely
                     // what you want).
 
-                    let ident = path.idents[0];
+                    let ident = path.segments[0].identifier;
 
                     match self.resolve_bare_identifier_pattern(ident) {
                         FoundStructOrEnumVariant(def)
@@ -4351,7 +4392,9 @@ impl Resolver {
                     }
 
                     // Check the types in the path pattern.
-                    for ty in path.types.iter() {
+                    for ty in path.segments
+                                  .iter()
+                                  .flat_map(|seg| seg.types.iter()) {
                         self.resolve_type(ty, visitor);
                     }
                 }
@@ -4375,7 +4418,7 @@ impl Resolver {
                                 path.span,
                                 fmt!("`%s` is not an enum variant or constant",
                                      self.session.str_of(
-                                         *path.idents.last())));
+                                         path.segments.last().identifier)))
                         }
                         None => {
                             self.resolve_error(path.span,
@@ -4384,7 +4427,9 @@ impl Resolver {
                     }
 
                     // Check the types in the path pattern.
-                    for ty in path.types.iter() {
+                    for ty in path.segments
+                                  .iter()
+                                  .flat_map(|s| s.types.iter()) {
                         self.resolve_type(ty, visitor);
                     }
                 }
@@ -4402,8 +4447,10 @@ impl Resolver {
                             self.resolve_error(
                                 path.span,
                                 fmt!("`%s` is not an enum variant, struct or const",
-                                     self.session.str_of(
-                                         *path.idents.last())));
+                                     self.session
+                                         .str_of(path.segments
+                                                     .last()
+                                                     .identifier)));
                         }
                         None => {
                             self.resolve_error(path.span,
@@ -4413,7 +4460,9 @@ impl Resolver {
                     }
 
                     // Check the types in the path pattern.
-                    for ty in path.types.iter() {
+                    for ty in path.segments
+                                  .iter()
+                                  .flat_map(|s| s.types.iter()) {
                         self.resolve_type(ty, visitor);
                     }
                 }
@@ -4448,7 +4497,7 @@ impl Resolver {
                             self.resolve_error(
                                 path.span,
                                 fmt!("`%s` does not name a structure",
-                                     self.idents_to_str(path.idents)));
+                                     self.path_idents_to_str(path)));
                         }
                     }
                 }
@@ -4510,7 +4559,7 @@ impl Resolver {
                         visitor: &mut ResolveVisitor)
                         -> Option<def> {
         // First, resolve the types.
-        for ty in path.types.iter() {
+        for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
             self.resolve_type(ty, visitor);
         }
 
@@ -4520,20 +4569,27 @@ impl Resolver {
                                                     namespace);
         }
 
-        let unqualified_def = self.resolve_identifier(
-            *path.idents.last(), namespace, check_ribs, path.span);
+        let unqualified_def = self.resolve_identifier(path.segments
+                                                          .last()
+                                                          .identifier,
+                                                      namespace,
+                                                      check_ribs,
+                                                      path.span);
 
-        if path.idents.len() > 1 {
-            let def = self.resolve_module_relative_path(
-                path, self.xray_context, namespace);
+        if path.segments.len() > 1 {
+            let def = self.resolve_module_relative_path(path,
+                                                        self.xray_context,
+                                                        namespace);
             match (def, unqualified_def) {
                 (Some(d), Some(ud)) if d == ud => {
                     self.session.add_lint(unnecessary_qualification,
-                                          id, path.span,
+                                          id,
+                                          path.span,
                                           ~"unnecessary qualification");
                 }
                 _ => ()
             }
+
             return def;
         }
 
@@ -4571,6 +4627,7 @@ impl Resolver {
                                                 xray: XrayFlag)
                                                 -> NameDefinition {
         // First, search children.
+        self.populate_module_if_necessary(containing_module);
         match containing_module.children.find(&name) {
             Some(child_name_bindings) => {
                 match (child_name_bindings.def_for_namespace(namespace),
@@ -4640,12 +4697,12 @@ impl Resolver {
 
     pub fn intern_module_part_of_path(@mut self, path: &Path) -> ~[ident] {
         let mut module_path_idents = ~[];
-        for (index, ident) in path.idents.iter().enumerate() {
-            if index == path.idents.len() - 1 {
+        for (index, segment) in path.segments.iter().enumerate() {
+            if index == path.segments.len() - 1 {
                 break;
             }
 
-            module_path_idents.push(*ident);
+            module_path_idents.push(segment.identifier);
         }
 
         return module_path_idents;
@@ -4681,7 +4738,7 @@ impl Resolver {
             }
         }
 
-        let name = *path.idents.last();
+        let name = path.segments.last().identifier;
         let def = match self.resolve_definition_of_name_in_module(containing_module,
                                                         name,
                                                         namespace,
@@ -4749,7 +4806,7 @@ impl Resolver {
             }
         }
 
-        let name = *path.idents.last();
+        let name = path.segments.last().identifier;
         match self.resolve_definition_of_name_in_module(containing_module,
                                                         name,
                                                         namespace,
@@ -4969,7 +5026,7 @@ impl Resolver {
                     Some(def) => {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `%s`",
-                               self.idents_to_str(path.idents));
+                               self.path_idents_to_str(path));
 
                         // First-class methods are not supported yet; error
                         // out here.
@@ -4989,8 +5046,7 @@ impl Resolver {
                         self.record_def(expr.id, def);
                     }
                     None => {
-                        let wrong_name = self.idents_to_str(
-                            path.idents);
+                        let wrong_name = self.path_idents_to_str(path);
                         if self.name_exists_in_scope_struct(wrong_name) {
                             self.resolve_error(expr.span,
                                         fmt!("unresolved name `%s`. \
@@ -5066,7 +5122,7 @@ impl Resolver {
                         self.resolve_error(
                             path.span,
                             fmt!("`%s` does not name a structure",
-                                 self.idents_to_str(path.idents)));
+                                 self.path_idents_to_str(path)));
                     }
                 }
 
@@ -5236,7 +5292,9 @@ impl Resolver {
                 }
 
                 // Look for trait children.
-                for (_, &child_name_bindings) in search_module.children.iter() {
+                self.populate_module_if_necessary(search_module);
+                for (_, &child_name_bindings) in
+                        search_module.children.iter() {
                     match child_name_bindings.def_for_namespace(TypeNS) {
                         Some(def) => {
                             match def {
@@ -5435,6 +5493,7 @@ impl Resolver {
         debug!("Dump of module `%s`:", self.module_to_str(module_));
 
         debug!("Children:");
+        self.populate_module_if_necessary(module_);
         for (&name, _) in module_.children.iter() {
             debug!("* %s", self.session.str_of(name));
         }
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index e72a568cba0..9502e02c279 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -117,10 +117,13 @@ pub fn trans(bcx: @mut Block, expr: @ast::expr) -> Callee {
 
     fn trans_def(bcx: @mut Block, def: ast::def, ref_expr: @ast::expr) -> Callee {
         match def {
-            ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
+            ast::def_fn(did, _) |
+            ast::def_static_method(did, ast::FromImpl(_), _) => {
                 fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id))
             }
-            ast::def_static_method(impl_did, Some(trait_did), _) => {
+            ast::def_static_method(impl_did,
+                                   ast::FromTrait(trait_did),
+                                   _) => {
                 fn_callee(bcx, meth::trans_static_method_callee(bcx, impl_did,
                                                                 trait_did,
                                                                 ref_expr.id))
@@ -280,6 +283,14 @@ pub fn trans_fn_ref_with_vtables(
                               self_ty: None,
                               tps: /*bad*/ type_params.to_owned() };
 
+    // Load the info for the appropriate trait if necessary.
+    match ty::trait_of_method(tcx, def_id) {
+        None => {}
+        Some(trait_id) => {
+            ty::populate_implementations_for_trait_if_necessary(tcx, trait_id)
+        }
+    }
+
     // We need to do a bunch of special handling for default methods.
     // We need to modify the def_id and our substs in order to monomorphize
     // the function.
@@ -300,7 +311,7 @@ pub fn trans_fn_ref_with_vtables(
             // So, what we need to do is find this substitution and
             // compose it with the one we already have.
 
-            let impl_id = ty::method(tcx, def_id).container_id;
+            let impl_id = ty::method(tcx, def_id).container_id();
             let method = ty::method(tcx, source_id);
             let trait_ref = ty::impl_trait_ref(tcx, impl_id)
                 .expect("could not find trait_ref for impl with \
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 2ac481cf730..0dfce6f42c3 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -559,7 +559,9 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
             v
           }
           ast::expr_path(ref pth) => {
-            assert_eq!(pth.types.len(), 0);
+            // Assert that there are no type parameters in this path.
+            assert!(pth.segments.iter().all(|seg| seg.types.is_empty()));
+
             let tcx = cx.tcx;
             match tcx.def_map.find(&e.id) {
                 Some(&ast::def_fn(def_id, _purity)) => {
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 6f981123f5f..7c81bfbda65 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -825,11 +825,13 @@ fn trans_def_datum_unadjusted(bcx: @mut Block,
     let _icx = push_ctxt("trans_def_datum_unadjusted");
 
     let fn_data = match def {
-        ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
+        ast::def_fn(did, _) |
+        ast::def_static_method(did, ast::FromImpl(_), _) => {
             callee::trans_fn_ref(bcx, did, ref_expr.id)
         }
-        ast::def_static_method(impl_did, Some(trait_did), _) => {
-            meth::trans_static_method_callee(bcx, impl_did,
+        ast::def_static_method(impl_did, ast::FromTrait(trait_did), _) => {
+            meth::trans_static_method_callee(bcx,
+                                             impl_did,
                                              trait_did,
                                              ref_expr.id)
         }
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index c0534b89f79..717dfbb6784 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -176,6 +176,10 @@ pub fn trans_method_callee(bcx: @mut Block,
         }) => {
             match bcx.fcx.param_substs {
                 Some(substs) => {
+                    ty::populate_implementations_for_trait_if_necessary(
+                        bcx.tcx(),
+                        trait_id);
+
                     let vtbl = find_vtable(bcx.tcx(), substs,
                                            p, b);
                     trans_monomorphized_callee(bcx, callee_id, this, mentry,
@@ -210,6 +214,8 @@ pub fn trans_static_method_callee(bcx: @mut Block,
            callee_id);
     let _indenter = indenter();
 
+    ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trait_id);
+
     // When we translate a static fn defined in a trait like:
     //
     //   trait<T1...Tn> Trait {
@@ -575,6 +581,8 @@ fn emit_vtable_methods(bcx: @mut Block,
                                     make a vtable for a type impl!")
     };
 
+    ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trt_id);
+
     let trait_method_def_ids = ty::trait_method_def_ids(tcx, trt_id);
     do trait_method_def_ids.map |method_def_id| {
         let ident = ty::method(tcx, *method_def_id).ident;
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 2a3b5d8c963..6f90953cd41 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -61,6 +61,12 @@ pub struct field {
 }
 
 #[deriving(Clone)]
+pub enum MethodContainer {
+    TraitContainer(ast::def_id),
+    ImplContainer(ast::def_id),
+}
+
+#[deriving(Clone)]
 pub struct Method {
     ident: ast::ident,
     generics: ty::Generics,
@@ -69,7 +75,7 @@ pub struct Method {
     explicit_self: ast::explicit_self_,
     vis: ast::visibility,
     def_id: ast::def_id,
-    container_id: ast::def_id,
+    container: MethodContainer,
 
     // If this method is provided, we need to know where it came from
     provided_source: Option<ast::def_id>
@@ -83,7 +89,7 @@ impl Method {
                explicit_self: ast::explicit_self_,
                vis: ast::visibility,
                def_id: ast::def_id,
-               container_id: ast::def_id,
+               container: MethodContainer,
                provided_source: Option<ast::def_id>)
                -> Method {
         // Check the invariants.
@@ -101,10 +107,17 @@ impl Method {
             explicit_self: explicit_self,
             vis: vis,
             def_id: def_id,
-            container_id: container_id,
+            container: container,
             provided_source: provided_source
         }
     }
+
+    pub fn container_id(&self) -> ast::def_id {
+        match self.container {
+            TraitContainer(id) => id,
+            ImplContainer(id) => id,
+        }
+    }
 }
 
 pub struct Impl {
@@ -324,7 +337,15 @@ struct ctxt_ {
     used_mut_nodes: @mut HashSet<ast::NodeId>,
 
     // vtable resolution information for impl declarations
-    impl_vtables: typeck::impl_vtable_map
+    impl_vtables: typeck::impl_vtable_map,
+
+    // The set of external nominal types whose implementations have been read.
+    // This is used for lazy resolution of methods.
+    populated_external_types: @mut HashSet<ast::def_id>,
+
+    // The set of external traits whose implementations have been read. This
+    // is used for lazy resolution of traits.
+    populated_external_traits: @mut HashSet<ast::def_id>,
 }
 
 pub enum tbox_flag {
@@ -938,6 +959,8 @@ pub fn mk_ctxt(s: session::Session,
         used_unsafe: @mut HashSet::new(),
         used_mut_nodes: @mut HashSet::new(),
         impl_vtables: @mut HashMap::new(),
+        populated_external_types: @mut HashSet::new(),
+        populated_external_traits: @mut HashSet::new(),
      }
 }
 
@@ -3612,8 +3635,7 @@ pub fn def_has_ty_params(def: ast::def) -> bool {
     }
 }
 
-pub fn provided_source(cx: ctxt, id: ast::def_id)
-    -> Option<ast::def_id> {
+pub fn provided_source(cx: ctxt, id: ast::def_id) -> Option<ast::def_id> {
     cx.provided_method_sources.find(&id).map_move(|x| *x)
 }
 
@@ -4553,3 +4575,135 @@ pub fn visitor_object_ty(tcx: ctxt,
                  ast::m_imm,
                  EmptyBuiltinBounds())))
 }
+
+/// Records a trait-to-implementation mapping.
+fn record_trait_implementation(tcx: ctxt,
+                               trait_def_id: def_id,
+                               implementation: @Impl) {
+    let implementation_list;
+    match tcx.trait_impls.find(&trait_def_id) {
+        None => {
+            implementation_list = @mut ~[];
+            tcx.trait_impls.insert(trait_def_id, implementation_list);
+        }
+        Some(&existing_implementation_list) => {
+            implementation_list = existing_implementation_list
+        }
+    }
+
+    implementation_list.push(implementation);
+}
+
+/// Populates the type context with all the implementations for the given type
+/// if necessary.
+pub fn populate_implementations_for_type_if_necessary(tcx: ctxt,
+                                                      type_id: ast::def_id) {
+    if type_id.crate == LOCAL_CRATE {
+        return
+    }
+    if tcx.populated_external_types.contains(&type_id) {
+        return
+    }
+
+    do csearch::each_implementation_for_type(tcx.sess.cstore, type_id)
+            |implementation_def_id| {
+        let implementation = @csearch::get_impl(tcx, implementation_def_id);
+
+        // Record the trait->implementation mappings, if applicable.
+        let associated_traits = csearch::get_impl_trait(tcx,
+                                                        implementation.did);
+        for trait_ref in associated_traits.iter() {
+            record_trait_implementation(tcx,
+                                        trait_ref.def_id,
+                                        implementation);
+        }
+
+        // For any methods that use a default implementation, add them to
+        // the map. This is a bit unfortunate.
+        for method in implementation.methods.iter() {
+            for source in method.provided_source.iter() {
+                tcx.provided_method_sources.insert(method.def_id, *source);
+            }
+        }
+
+        // If this is an inherent implementation, record it.
+        if associated_traits.is_none() {
+            let implementation_list;
+            match tcx.inherent_impls.find(&type_id) {
+                None => {
+                    implementation_list = @mut ~[];
+                    tcx.inherent_impls.insert(type_id, implementation_list);
+                }
+                Some(&existing_implementation_list) => {
+                    implementation_list = existing_implementation_list;
+                }
+            }
+            implementation_list.push(implementation);
+        }
+
+        // Store the implementation info.
+        tcx.impls.insert(implementation_def_id, implementation);
+    }
+
+    tcx.populated_external_types.insert(type_id);
+}
+
+/// Populates the type context with all the implementations for the given
+/// trait if necessary.
+pub fn populate_implementations_for_trait_if_necessary(
+        tcx: ctxt,
+        trait_id: ast::def_id) {
+    if trait_id.crate == LOCAL_CRATE {
+        return
+    }
+    if tcx.populated_external_traits.contains(&trait_id) {
+        return
+    }
+
+    do csearch::each_implementation_for_trait(tcx.sess.cstore, trait_id)
+            |implementation_def_id| {
+        let implementation = @csearch::get_impl(tcx, implementation_def_id);
+
+        // Record the trait->implementation mapping.
+        record_trait_implementation(tcx, trait_id, implementation);
+
+        // For any methods that use a default implementation, add them to
+        // the map. This is a bit unfortunate.
+        for method in implementation.methods.iter() {
+            for source in method.provided_source.iter() {
+                tcx.provided_method_sources.insert(method.def_id, *source);
+            }
+        }
+
+        // Store the implementation info.
+        tcx.impls.insert(implementation_def_id, implementation);
+    }
+
+    tcx.populated_external_traits.insert(trait_id);
+}
+
+/// If the given def ID describes a trait method, returns the ID of the trait
+/// that the method belongs to. Otherwise, returns `None`.
+pub fn trait_of_method(tcx: ctxt, def_id: ast::def_id)
+                       -> Option<ast::def_id> {
+    match tcx.methods.find(&def_id) {
+        Some(method_descriptor) => {
+            match method_descriptor.container {
+                TraitContainer(id) => return Some(id),
+                _ => {}
+            }
+        }
+        None => {}
+    }
+
+    // If the method was in the local crate, then if we got here we know the
+    // answer is negative.
+    if def_id.crate == LOCAL_CRATE {
+        return None
+    }
+
+    let result = csearch::get_trait_of_method(tcx.cstore, def_id, tcx);
+
+    result
+}
+
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index db76d75a5a5..17b4716ad50 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -63,7 +63,6 @@ use middle::typeck::rscope::RegionParamNames;
 use middle::typeck::lookup_def_tcx;
 
 use std::result;
-use std::vec;
 use syntax::abi::AbiSet;
 use syntax::{ast, ast_util};
 use syntax::codemap::span;
@@ -150,7 +149,8 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Clone + 'static>(
     // If the type is parameterized by the this region, then replace this
     // region with the current anon region binding (in other words,
     // whatever & would get replaced with).
-    let regions = match (&decl_generics.region_param, &path.rp) {
+    let regions = match (&decl_generics.region_param,
+                         &path.segments.last().lifetime) {
         (&None, &None) => {
             opt_vec::Empty
         }
@@ -169,20 +169,34 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Clone + 'static>(
         }
         (&Some(_), &Some(_)) => {
             opt_vec::with(
-                ast_region_to_region(this, rscope, path.span, &path.rp))
+                ast_region_to_region(this,
+                                     rscope,
+                                     path.span,
+                                     &path.segments.last().lifetime))
         }
     };
 
     // Convert the type parameters supplied by the user.
-    if !vec::same_length(*decl_generics.type_param_defs, path.types) {
+    let supplied_type_parameter_count =
+        path.segments.iter().flat_map(|s| s.types.iter()).len();
+    if decl_generics.type_param_defs.len() != supplied_type_parameter_count {
         this.tcx().sess.span_fatal(
             path.span,
             fmt!("wrong number of type arguments: expected %u but found %u",
-                 decl_generics.type_param_defs.len(), path.types.len()));
+                 decl_generics.type_param_defs.len(),
+                 supplied_type_parameter_count));
+    }
+    let tps = path.segments
+                  .iter()
+                  .flat_map(|s| s.types.iter())
+                  .map(|a_t| ast_ty_to_ty(this, rscope, a_t))
+                  .collect();
+
+    substs {
+        regions: ty::NonerasedRegions(regions),
+        self_ty: self_ty,
+        tps: tps
     }
-    let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, a_t));
-
-    substs {regions:ty::NonerasedRegions(regions), self_ty:self_ty, tps:tps}
 }
 
 pub fn ast_path_to_substs_and_ty<AC:AstConv,
@@ -272,8 +286,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Clone + 'static>(
         match a_seq_ty.ty.node {
             ast::ty_vec(ref mt) => {
                 let mut mt = ast_mt_to_mt(this, rscope, mt);
-                if a_seq_ty.mutbl == ast::m_mutbl ||
-                        a_seq_ty.mutbl == ast::m_const {
+                if a_seq_ty.mutbl == ast::m_mutbl {
                     mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl };
                 }
                 return ty::mk_evec(tcx, mt, vst);
@@ -326,7 +339,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Clone + 'static>(
                        path: &ast::Path,
                        flags: uint) {
         if (flags & NO_TPS) != 0u {
-            if path.types.len() > 0u {
+            if !path.segments.iter().all(|s| s.types.is_empty()) {
                 tcx.sess.span_err(
                     path.span,
                     "type parameters are not allowed on this type");
@@ -334,7 +347,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Clone + 'static>(
         }
 
         if (flags & NO_REGIONS) != 0u {
-            if path.rp.is_some() {
+            if path.segments.last().lifetime.is_some() {
                 tcx.sess.span_err(
                     path.span,
                     "region parameters are not allowed on this type");
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index b7114e60283..628ceccd61e 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -128,7 +128,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
                 Some((enm, var)) => {
                     // Assign the pattern the type of the *enum*, not the variant.
                     let enum_tpt = ty::lookup_item_type(tcx, enm);
-                    instantiate_path(pcx.fcx, path, enum_tpt, pat.span, pat.id);
+                    instantiate_path(pcx.fcx,
+                                     path,
+                                     enum_tpt,
+                                     v_def,
+                                     pat.span,
+                                     pat.id);
 
                     // check that the type of the value being matched is a subtype
                     // of the type of the pattern:
@@ -185,7 +190,12 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: &ast::Path,
             } else {
                 ctor_tpt
             };
-            instantiate_path(pcx.fcx, path, struct_tpt, pat.span, pat.id);
+            instantiate_path(pcx.fcx,
+                             path,
+                             struct_tpt,
+                             s_def,
+                             pat.span,
+                             pat.id);
 
             // Check that the type of the value being matched is a subtype of
             // the type of the pattern.
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index c15f6a25445..c20ccafe82c 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -102,7 +102,7 @@ use std::vec;
 use extra::list::Nil;
 use syntax::ast::{def_id, sty_value, sty_region, sty_box};
 use syntax::ast::{sty_uniq, sty_static, NodeId};
-use syntax::ast::{m_const, m_mutbl, m_imm};
+use syntax::ast::{m_mutbl, m_imm};
 use syntax::ast;
 use syntax::ast_map;
 
@@ -350,6 +350,10 @@ impl<'self> LookupContext<'self> {
         let opt_applicable_traits = trait_map.find(&self.expr.id);
         for applicable_traits in opt_applicable_traits.iter() {
             for trait_did in applicable_traits.iter() {
+                ty::populate_implementations_for_trait_if_necessary(
+                    self.tcx(),
+                    *trait_did);
+
                 // Look for explicit implementations.
                 let opt_impl_infos = self.tcx().trait_impls.find(trait_did);
                 for impl_infos in opt_impl_infos.iter() {
@@ -534,6 +538,10 @@ impl<'self> LookupContext<'self> {
 
 
     fn push_inherent_impl_candidates_for_type(&self, did: def_id) {
+        // Read the inherent implementation candidates for this type from the
+        // metadata if necessary.
+        ty::populate_implementations_for_type_if_necessary(self.tcx(), did);
+
         let opt_impl_infos = self.tcx().inherent_impls.find(&did);
         for impl_infos in opt_impl_infos.iter() {
             for impl_info in impl_infos.iter() {
@@ -700,7 +708,7 @@ impl<'self> LookupContext<'self> {
             ty_evec(mt, vstore_fixed(_)) => {
                 // First try to borrow to a slice
                 let entry = self.search_for_some_kind_of_autorefd_method(
-                    AutoBorrowVec, autoderefs, [m_const, m_imm, m_mutbl],
+                    AutoBorrowVec, autoderefs, [m_imm, m_mutbl],
                     |m,r| ty::mk_evec(tcx,
                                       ty::mt {ty:mt.ty, mutbl:m},
                                       vstore_slice(r)));
@@ -709,7 +717,7 @@ impl<'self> LookupContext<'self> {
 
                 // Then try to borrow to a slice *and* borrow a pointer.
                 self.search_for_some_kind_of_autorefd_method(
-                    AutoBorrowVecRef, autoderefs, [m_const, m_imm, m_mutbl],
+                    AutoBorrowVecRef, autoderefs, [m_imm, m_mutbl],
                     |m,r| {
                         let slice_ty = ty::mk_evec(tcx,
                                                    ty::mt {ty:mt.ty, mutbl:m},
@@ -744,7 +752,7 @@ impl<'self> LookupContext<'self> {
                 // Coerce ~/@/&Trait instances to &Trait.
 
                 self.search_for_some_kind_of_autorefd_method(
-                    AutoBorrowObj, autoderefs, [m_const, m_imm, m_mutbl],
+                    AutoBorrowObj, autoderefs, [m_imm, m_mutbl],
                     |trt_mut, reg| {
                         ty::mk_trait(tcx, trt_did, trt_substs.clone(),
                                      RegionTraitStore(reg), trt_mut, b)
@@ -779,7 +787,7 @@ impl<'self> LookupContext<'self> {
             ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_struct(*) | ty_tup(*) |
             ty_estr(*) | ty_evec(*) | ty_trait(*) | ty_closure(*) => {
                 self.search_for_some_kind_of_autorefd_method(
-                    AutoPtr, autoderefs, [m_const, m_imm, m_mutbl],
+                    AutoPtr, autoderefs, [m_imm, m_mutbl],
                     |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m}))
             }
 
@@ -1270,18 +1278,10 @@ impl<'self> LookupContext<'self> {
         }
 
         fn mutability_matches(self_mutbl: ast::mutability,
-                              candidate_mutbl: ast::mutability) -> bool {
+                              candidate_mutbl: ast::mutability)
+                              -> bool {
             //! True if `self_mutbl <: candidate_mutbl`
-
-            match (self_mutbl, candidate_mutbl) {
-                (_, m_const) => true,
-                (m_mutbl, m_mutbl) => true,
-                (m_imm, m_imm) => true,
-                (m_mutbl, m_imm) => false,
-                (m_imm, m_mutbl) => false,
-                (m_const, m_imm) => false,
-                (m_const, m_mutbl) => false,
-            }
+            self_mutbl == candidate_mutbl
         }
     }
 
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 0c8f2229424..706d6871f86 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -377,7 +377,7 @@ impl Visitor<()> for GatherLocalsVisitor {
                   if pat_util::pat_is_binding(self.fcx.ccx.tcx.def_map, p) => {
                 self.assign(p.id, None);
                 debug!("Pattern binding %s is assigned to %s",
-                       self.tcx.sess.str_of(path.idents[0]),
+                       self.tcx.sess.str_of(path.segments[0].identifier),
                        self.fcx.infcx().ty_to_str(
                            self.fcx.inh.locals.get_copy(&p.id)));
               }
@@ -1132,8 +1132,160 @@ pub enum DerefArgs {
     DoDerefArgs
 }
 
-pub fn break_here() {
-    debug!("break here!");
+// Given the provenance of a static method, returns the generics of the static
+// method's container.
+fn generics_of_static_method_container(type_context: ty::ctxt,
+                                       provenance: ast::MethodProvenance)
+                                       -> ty::Generics {
+    match provenance {
+        ast::FromTrait(trait_def_id) => {
+            ty::lookup_trait_def(type_context, trait_def_id).generics
+        }
+        ast::FromImpl(impl_def_id) => {
+            ty::lookup_item_type(type_context, impl_def_id).generics
+        }
+    }
+}
+
+// Verifies that type parameters supplied in paths are in the right
+// locations.
+fn check_type_parameter_positions_in_path(function_context: @mut FnCtxt,
+                                          path: &ast::Path,
+                                          def: ast::def) {
+    // We only care about checking the case in which the path has two or
+    // more segments.
+    if path.segments.len() < 2 {
+        return
+    }
+
+    // Verify that no lifetimes or type parameters are present anywhere
+    // except the final two elements of the path.
+    for i in range(0, path.segments.len() - 2) {
+        match path.segments[i].lifetime {
+            None => {}
+            Some(lifetime) => {
+                function_context.tcx()
+                                .sess
+                                .span_err(lifetime.span,
+                                          "lifetime parameters may not \
+                                           appear here")
+            }
+        }
+
+        for typ in path.segments[i].types.iter() {
+            function_context.tcx()
+                            .sess
+                            .span_err(typ.span,
+                                      "type parameters may not appear here")
+        }
+    }
+
+    // If there are no parameters at all, there is nothing more to do; the
+    // rest of typechecking will (attempt to) infer everything.
+    if path.segments
+           .iter()
+           .all(|s| s.lifetime.is_none() && s.types.is_empty()) {
+        return
+    }
+
+    match def {
+        // If this is a static method of a trait or implementation, then
+        // ensure that the segment of the path which names the trait or
+        // implementation (the penultimate segment) is annotated with the
+        // right number of type parameters.
+        ast::def_static_method(_, provenance, _) => {
+            let generics =
+                generics_of_static_method_container(function_context.ccx.tcx,
+                                                    provenance);
+            let name = match provenance {
+                ast::FromTrait(_) => "trait",
+                ast::FromImpl(_) => "impl",
+            };
+
+            let trait_segment = &path.segments[path.segments.len() - 2];
+
+            // Make sure lifetime parameterization agrees with the trait or
+            // implementation type.
+            match (generics.region_param, trait_segment.lifetime) {
+                (Some(_), None) => {
+                    function_context.tcx()
+                                    .sess
+                                    .span_err(path.span,
+                                              fmt!("this %s has a lifetime \
+                                                    parameter but no \
+                                                    lifetime was specified",
+                                                   name))
+                }
+                (None, Some(_)) => {
+                    function_context.tcx()
+                                    .sess
+                                    .span_err(path.span,
+                                              fmt!("this %s has no lifetime \
+                                                    parameter but a lifetime \
+                                                    was specified",
+                                                   name))
+                }
+                (Some(_), Some(_)) | (None, None) => {}
+            }
+
+            // Make sure the number of type parameters supplied on the trait
+            // or implementation segment equals the number of type parameters
+            // on the trait or implementation definition.
+            let trait_type_parameter_count = generics.type_param_defs.len();
+            let supplied_type_parameter_count = trait_segment.types.len();
+            if trait_type_parameter_count != supplied_type_parameter_count {
+                let trait_count_suffix = if trait_type_parameter_count == 1 {
+                    ""
+                } else {
+                    "s"
+                };
+                let supplied_count_suffix =
+                    if supplied_type_parameter_count == 1 {
+                        ""
+                    } else {
+                        "s"
+                    };
+                function_context.tcx()
+                                .sess
+                                .span_err(path.span,
+                                          fmt!("the %s referenced by this \
+                                                path has %u type \
+                                                parameter%s, but %u type \
+                                                parameter%s were supplied",
+                                               name,
+                                               trait_type_parameter_count,
+                                               trait_count_suffix,
+                                               supplied_type_parameter_count,
+                                               supplied_count_suffix))
+            }
+        }
+        _ => {
+            // Verify that no lifetimes or type parameters are present on
+            // the penultimate segment of the path.
+            let segment = &path.segments[path.segments.len() - 2];
+            match segment.lifetime {
+                None => {}
+                Some(lifetime) => {
+                    function_context.tcx()
+                                    .sess
+                                    .span_err(lifetime.span,
+                                              "lifetime parameters may not
+                                               appear here")
+                }
+            }
+            for typ in segment.types.iter() {
+                function_context.tcx()
+                                .sess
+                                .span_err(typ.span,
+                                          "type parameters may not appear \
+                                           here");
+                function_context.tcx()
+                                .sess
+                                .span_note(typ.span,
+                                           fmt!("this is a %?", def));
+            }
+        }
+    }
 }
 
 /// Invariant:
@@ -2333,8 +2485,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
       ast::expr_path(ref pth) => {
         let defn = lookup_def(fcx, pth.span, id);
 
+        check_type_parameter_positions_in_path(fcx, pth, defn);
         let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
-        instantiate_path(fcx, pth, tpt, expr.span, expr.id);
+        instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id);
       }
       ast::expr_self => {
         let definition = lookup_def(fcx, expr.span, id);
@@ -3141,12 +3294,16 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
 pub fn instantiate_path(fcx: @mut FnCtxt,
                         pth: &ast::Path,
                         tpt: ty_param_bounds_and_ty,
+                        def: ast::def,
                         span: span,
                         node_id: ast::NodeId) {
     debug!(">>> instantiate_path");
 
     let ty_param_count = tpt.generics.type_param_defs.len();
-    let ty_substs_len = pth.types.len();
+    let mut ty_substs_len = 0;
+    for segment in pth.segments.iter() {
+        ty_substs_len += segment.types.len()
+    }
 
     debug!("tpt=%s ty_param_count=%? ty_substs_len=%?",
            tpt.repr(fcx.tcx()),
@@ -3155,7 +3312,7 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
 
     // determine the region bound, using the value given by the user
     // (if any) and otherwise using a fresh region variable
-    let regions = match pth.rp {
+    let regions = match pth.segments.last().lifetime {
         Some(_) => { // user supplied a lifetime parameter...
             match tpt.generics.region_param {
                 None => { // ...but the type is not lifetime parameterized!
@@ -3165,7 +3322,10 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
                 }
                 Some(_) => { // ...and the type is lifetime parameterized, ok.
                     opt_vec::with(
-                        ast_region_to_region(fcx, fcx, span, &pth.rp))
+                        ast_region_to_region(fcx,
+                                             fcx,
+                                             span,
+                                             &pth.segments.last().lifetime))
                 }
             }
         }
@@ -3174,6 +3334,21 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
         }
     };
 
+    // Special case: If there is a self parameter, omit it from the list of
+    // type parameters.
+    //
+    // Here we calculate the "user type parameter count", which is the number
+    // of type parameters actually manifest in the AST. This will differ from
+    // the internal type parameter count when there are self types involved.
+    let (user_type_parameter_count, self_parameter_index) = match def {
+        ast::def_static_method(_, provenance @ ast::FromTrait(_), _) => {
+            let generics = generics_of_static_method_container(fcx.ccx.tcx,
+                                                               provenance);
+            (ty_param_count - 1, Some(generics.type_param_defs.len()))
+        }
+        _ => (ty_param_count, None),
+    };
+
     // determine values for type parameters, using the values given by
     // the user (if any) and otherwise using fresh type variables
     let tps = if ty_substs_len == 0 {
@@ -3182,34 +3357,51 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
         fcx.ccx.tcx.sess.span_err
             (span, "this item does not take type parameters");
         fcx.infcx().next_ty_vars(ty_param_count)
-    } else if ty_substs_len > ty_param_count {
+    } else if ty_substs_len > user_type_parameter_count {
         fcx.ccx.tcx.sess.span_err
             (span,
              fmt!("too many type parameters provided: expected %u, found %u",
-                  ty_param_count, ty_substs_len));
+                  user_type_parameter_count, ty_substs_len));
         fcx.infcx().next_ty_vars(ty_param_count)
-    } else if ty_substs_len < ty_param_count {
-        let is_static_method = match fcx.ccx.tcx.def_map.find(&node_id) {
-            Some(&ast::def_static_method(*)) => true,
-            _ => false
-        };
+    } else if ty_substs_len < user_type_parameter_count {
         fcx.ccx.tcx.sess.span_err
             (span,
              fmt!("not enough type parameters provided: expected %u, found %u",
-                  ty_param_count, ty_substs_len));
-        if is_static_method {
-            fcx.ccx.tcx.sess.span_note
-                (span, "Static methods have an extra implicit type parameter -- \
-                 did you omit the type parameter for the `Self` type?");
-        }
+                  user_type_parameter_count, ty_substs_len));
         fcx.infcx().next_ty_vars(ty_param_count)
     } else {
-        pth.types.map(|aty| fcx.to_ty(aty))
+        // Build up the list of type parameters, inserting the self parameter
+        // at the appropriate position.
+        let mut result = ~[];
+        let mut pushed = false;
+        for (i, ast_type) in pth.segments
+                                .iter()
+                                .flat_map(|segment| segment.types.iter())
+                                .enumerate() {
+            match self_parameter_index {
+                Some(index) if index == i => {
+                    result.push(fcx.infcx().next_ty_vars(1)[0]);
+                    pushed = true;
+                }
+                _ => {}
+            }
+            result.push(fcx.to_ty(ast_type))
+        }
+
+        // If the self parameter goes at the end, insert it there.
+        if !pushed && self_parameter_index.is_some() {
+            result.push(fcx.infcx().next_ty_vars(1)[0])
+        }
+
+        assert_eq!(result.len(), ty_param_count)
+        result
     };
 
-    let substs = substs {regions: ty::NonerasedRegions(regions),
-                         self_ty: None,
-                         tps: tps };
+    let substs = substs {
+        regions: ty::NonerasedRegions(regions),
+        self_ty: None,
+        tps: tps
+    };
     fcx.write_ty_substs(node_id, tpt.ty, substs);
 
     debug!("<<<");
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 715c25c4a19..670553f569a 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -136,6 +136,9 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
         // ...and here trait_ref is each bound that was declared on A,
         // expressed in terms of the type parameters.
 
+        ty::populate_implementations_for_trait_if_necessary(tcx,
+                                                            trait_ref.def_id);
+
         // Substitute the values of the type parameters that may
         // appear in the bound.
         let trait_ref = substs.map_default(trait_ref, |substs| {
@@ -321,6 +324,10 @@ fn search_for_vtable(vcx: &VtableContext,
     let mut found = ~[];
     let mut impls_seen = HashSet::new();
 
+    // Load the implementations from external metadata if necessary.
+    ty::populate_implementations_for_trait_if_necessary(tcx,
+                                                        trait_ref.def_id);
+
     // XXX: this is a bad way to do this, since we do
     // pointless allocations.
     let impls = tcx.trait_impls.find(&trait_ref.def_id)
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index b659f6081b1..2aa4e28f1a4 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -15,12 +15,11 @@
 // each trait in the system to its implementations.
 
 
-use metadata::csearch::{each_path, get_impl_trait};
+use metadata::csearch::{each_impl, get_impl_trait};
 use metadata::csearch;
 use metadata::cstore::iter_crate_data;
-use metadata::decoder::{dl_def, dl_field, dl_impl};
 use middle::ty::get;
-use middle::ty::{lookup_item_type, subst};
+use middle::ty::{ImplContainer, lookup_item_type, subst};
 use middle::ty::{substs, t, ty_bool, ty_bot, ty_box, ty_enum, ty_err};
 use middle::ty::{ty_estr, ty_evec, ty_float, ty_infer, ty_int, ty_nil};
 use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr};
@@ -43,13 +42,12 @@ use syntax::ast;
 use syntax::ast_map::node_item;
 use syntax::ast_map;
 use syntax::ast_util::{def_id_of_def, local_def};
-use syntax::codemap::{span, dummy_sp};
+use syntax::codemap::span;
 use syntax::opt_vec;
 use syntax::visit;
 use syntax::parse;
-use util::ppaux::ty_to_str;
 
-use std::hashmap::{HashMap, HashSet};
+use std::hashmap::HashSet;
 use std::result::Ok;
 use std::vec;
 
@@ -150,19 +148,12 @@ pub fn CoherenceChecker(crate_context: @mut CrateCtxt) -> CoherenceChecker {
     CoherenceChecker {
         crate_context: crate_context,
         inference_context: new_infer_ctxt(crate_context.tcx),
-
-        base_type_def_ids: @mut HashMap::new(),
     }
 }
 
 pub struct CoherenceChecker {
     crate_context: @mut CrateCtxt,
     inference_context: @mut InferCtxt,
-
-    // A mapping from implementations to the corresponding base type
-    // definition ID.
-
-    base_type_def_ids: @mut HashMap<def_id,def_id>,
 }
 
 struct CoherenceCheckVisitor { cc: CoherenceChecker }
@@ -321,9 +312,6 @@ impl CoherenceChecker {
                 if associated_traits.len() == 0 {
                     self.add_inherent_impl(base_type_def_id, implementation);
                 }
-
-                self.base_type_def_ids.insert(local_def(item.id),
-                                              base_type_def_id);
             }
         }
 
@@ -680,9 +668,6 @@ impl CoherenceChecker {
         let tcx = self.crate_context.tcx;
         let implementation = @csearch::get_impl(tcx, impl_def_id);
 
-        debug!("coherence: adding impl from external crate: %s",
-               ty::item_path_str(tcx, implementation.did));
-
         // Make sure we don't visit the same implementation multiple times.
         if !impls_seen.insert(implementation.did) {
             // Skip this one.
@@ -690,25 +675,11 @@ impl CoherenceChecker {
         }
         // Good. Continue.
 
-        let self_type = lookup_item_type(tcx, implementation.did);
-        let associated_traits = get_impl_trait(tcx,
-                                               implementation.did);
+        let _ = lookup_item_type(tcx, implementation.did);
+        let associated_traits = get_impl_trait(tcx, implementation.did);
 
-        // Do a sanity check to make sure that inherent methods have base
-        // types.
-        if associated_traits.is_none() {
-            match get_base_type_def_id(self.inference_context,
-                                       dummy_sp(),
-                                       self_type.ty) {
-                None => {
-                    tcx.sess.bug(fmt!("no base type for external impl with no \
-                                      trait: %s (type %s)!",
-                                     tcx.sess.str_of(implementation.ident),
-                                     ty_to_str(tcx, self_type.ty)));
-                }
-                Some(_) => {} // Nothing to do.
-            }
-        }
+        // Do a sanity check.
+        assert!(associated_traits.is_some());
 
         // Record all the trait methods.
         for trait_ref in associated_traits.iter() {
@@ -723,25 +694,6 @@ impl CoherenceChecker {
             }
         }
 
-        // Add the implementation to the mapping from implementation to base
-        // type def ID, if there is a base type for this implementation.
-        match get_base_type_def_id(self.inference_context,
-                                   dummy_sp(),
-                                   self_type.ty) {
-            None => {} // Nothing to do.
-            Some(base_type_def_id) => {
-                // inherent methods apply to `impl Type` but not
-                // `impl Trait for Type`:
-                if associated_traits.is_none() {
-                    self.add_inherent_impl(base_type_def_id,
-                                           implementation);
-                }
-
-                self.base_type_def_ids.insert(implementation.did,
-                                              base_type_def_id);
-            }
-        }
-
         tcx.impls.insert(implementation.did, implementation);
     }
 
@@ -752,15 +704,10 @@ impl CoherenceChecker {
 
         let crate_store = self.crate_context.tcx.sess.cstore;
         do iter_crate_data(crate_store) |crate_number, _crate_metadata| {
-            do each_path(crate_store, crate_number) |_, def_like, _| {
-                match def_like {
-                    dl_impl(def_id) => {
-                        self.add_external_impl(&mut impls_seen, def_id)
-                    }
-                    dl_def(_) | dl_field => (),   // Skip this.
-                }
-                true
-            };
+            do each_impl(crate_store, crate_number) |def_id| {
+                assert_eq!(crate_number, def_id.crate);
+                self.add_external_impl(&mut impls_seen, def_id)
+            }
         }
     }
 
@@ -892,7 +839,7 @@ fn subst_receiver_types_in_method_ty(tcx: ty::ctxt,
         method.explicit_self,
         method.vis,
         new_def_id,
-        impl_id,
+        ImplContainer(impl_id),
         provided_source
     )
 }
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index cb0244bb610..63317d4ca5c 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -32,7 +32,8 @@ are represented as `ty_param()` instances.
 
 
 use metadata::csearch;
-use middle::ty::{substs, ty_param_bounds_and_ty};
+use middle::ty::{ImplContainer, MethodContainer, TraitContainer, substs};
+use middle::ty::{ty_param_bounds_and_ty};
 use middle::ty;
 use middle::subst::Subst;
 use middle::typeck::astconv::{AstConv, ty_of_arg};
@@ -388,7 +389,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
             // assume public, because this is only invoked on trait methods
             ast::public,
             local_def(*m_id),
-            local_def(trait_id),
+            TraitContainer(local_def(trait_id)),
             None
         )
     }
@@ -744,7 +745,7 @@ pub struct ConvertedMethod {
 }
 
 pub fn convert_methods(ccx: &CrateCtxt,
-                       container_id: ast::NodeId,
+                       container: MethodContainer,
                        ms: &[@ast::method],
                        untransformed_rcvr_ty: ty::t,
                        rcvr_ty_generics: &ty::Generics,
@@ -758,11 +759,14 @@ pub fn convert_methods(ccx: &CrateCtxt,
         let m_ty_generics =
             ty_generics(ccx, rcvr_ty_generics.region_param, &m.generics,
                         num_rcvr_ty_params);
-        let mty =
-            @ty_of_method(ccx, container_id, *m, rcvr_ty_generics.region_param,
-                          untransformed_rcvr_ty,
-                          rcvr_ast_generics, rcvr_visibility,
-                          &m.generics);
+        let mty = @ty_of_method(ccx,
+                                container,
+                                *m,
+                                rcvr_ty_generics.region_param,
+                                untransformed_rcvr_ty,
+                                rcvr_ast_generics,
+                                rcvr_visibility,
+                                &m.generics);
         let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
         tcx.tcache.insert(
             local_def(m.id),
@@ -785,7 +789,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
     }).collect();
 
     fn ty_of_method(ccx: &CrateCtxt,
-                    container_id: ast::NodeId,
+                    container: MethodContainer,
                     m: &ast::method,
                     rp: Option<ty::region_variance>,
                     untransformed_rcvr_ty: ty::t,
@@ -817,7 +821,7 @@ pub fn convert_methods(ccx: &CrateCtxt,
             m.explicit_self.node,
             method_vis,
             local_def(m.id),
-            local_def(container_id),
+            container,
             None
         )
     }
@@ -877,8 +881,12 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
             it.vis
         };
 
-        let cms = convert_methods(ccx, it.id, *ms, selfty,
-                                  &i_ty_generics, generics,
+        let cms = convert_methods(ccx,
+                                  ImplContainer(local_def(it.id)),
+                                  *ms,
+                                  selfty,
+                                  &i_ty_generics,
+                                  generics,
                                   parent_visibility);
         for t in opt_trait_ref.iter() {
             // Prevent the builtin kind traits from being manually implemented.
@@ -901,9 +909,12 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
           let untransformed_rcvr_ty = ty::mk_self(tcx, local_def(it.id));
           let (ty_generics, _) = mk_item_substs(ccx, generics, rp,
                                                 Some(untransformed_rcvr_ty));
-          let _ = convert_methods(ccx, it.id, provided_methods,
+          let _ = convert_methods(ccx,
+                                  TraitContainer(local_def(it.id)),
+                                  provided_methods,
                                   untransformed_rcvr_ty,
-                                  &ty_generics, generics,
+                                  &ty_generics,
+                                  generics,
                                   it.vis);
 
           // We need to do this *after* converting methods, since
diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs
index 2e337f5f57b..86c0736090c 100644
--- a/src/librustc/middle/typeck/infer/glb.rs
+++ b/src/librustc/middle/typeck/infer/glb.rs
@@ -21,7 +21,7 @@ use middle::typeck::infer::{cres, InferCtxt};
 use middle::typeck::infer::{TypeTrace, Subtype};
 use middle::typeck::infer::fold_regions_in_sig;
 use middle::typeck::isr_alist;
-use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl};
+use syntax::ast::{Many, Once, extern_fn, impure_fn, m_imm, m_mutbl};
 use syntax::ast::{unsafe_fn};
 use syntax::ast::{Onceness, purity};
 use util::common::{indenter};
@@ -52,16 +52,6 @@ impl Combine for Glb {
         match (a.mutbl, b.mutbl) {
           // If one side or both is mut, then the GLB must use
           // the precise type from the mut side.
-          (m_mutbl, m_const) => {
-            Sub(**self).tys(a.ty, b.ty).chain(|_t| {
-                Ok(ty::mt {ty: a.ty, mutbl: m_mutbl})
-            })
-          }
-          (m_const, m_mutbl) => {
-            Sub(**self).tys(b.ty, a.ty).chain(|_t| {
-                Ok(ty::mt {ty: b.ty, mutbl: m_mutbl})
-            })
-          }
           (m_mutbl, m_mutbl) => {
             eq_tys(self, a.ty, b.ty).then(|| {
                 Ok(ty::mt {ty: a.ty, mutbl: m_mutbl})
@@ -70,22 +60,12 @@ impl Combine for Glb {
 
           // If one side or both is immutable, we can use the GLB of
           // both sides but mutbl must be `m_imm`.
-          (m_imm, m_const) |
-          (m_const, m_imm) |
           (m_imm, m_imm) => {
             self.tys(a.ty, b.ty).chain(|t| {
                 Ok(ty::mt {ty: t, mutbl: m_imm})
             })
           }
 
-          // If both sides are const, then we can use GLB of both
-          // sides and mutbl of only `m_const`.
-          (m_const, m_const) => {
-            self.tys(a.ty, b.ty).chain(|t| {
-                Ok(ty::mt {ty: t, mutbl: m_const})
-            })
-          }
-
           // There is no mutual subtype of these combinations.
           (m_mutbl, m_imm) |
           (m_imm, m_mutbl) => {
diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs
index 4f38e2aaac6..50bddaacc3f 100644
--- a/src/librustc/middle/typeck/infer/lub.rs
+++ b/src/librustc/middle/typeck/infer/lub.rs
@@ -24,7 +24,7 @@ use middle::typeck::isr_alist;
 use util::ppaux::mt_to_str;
 
 use extra::list;
-use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn};
+use syntax::ast::{Many, Once, extern_fn, impure_fn};
 use syntax::ast::{unsafe_fn};
 use syntax::ast::{Onceness, purity};
 
@@ -55,14 +55,13 @@ impl Combine for Lub {
                mt_to_str(tcx, a),
                mt_to_str(tcx, b));
 
-        let m = if a.mutbl == b.mutbl {
-            a.mutbl
-        } else {
-            m_const
-        };
+        if a.mutbl != b.mutbl {
+            return Err(ty::terr_mutability)
+        }
 
+        let m = a.mutbl;
         match m {
-          m_imm | m_const => {
+          m_imm => {
             self.tys(a.ty, b.ty).chain(|t| Ok(ty::mt {ty: t, mutbl: m}) )
           }
 
@@ -71,11 +70,7 @@ impl Combine for Lub {
                 eq_tys(self, a.ty, b.ty).then(|| {
                     Ok(ty::mt {ty: a.ty, mutbl: m})
                 })
-            }).chain_err(|_e| {
-                self.tys(a.ty, b.ty).chain(|t| {
-                    Ok(ty::mt {ty: t, mutbl: m_const})
-                })
-            })
+            }).chain_err(|e| Err(e))
           }
         }
     }
diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs
index 5a4ea1c9f1f..a00f018ceab 100644
--- a/src/librustc/middle/typeck/infer/sub.rs
+++ b/src/librustc/middle/typeck/infer/sub.rs
@@ -26,7 +26,7 @@ use util::ppaux::bound_region_to_str;
 
 use extra::list::Nil;
 use extra::list;
-use syntax::ast::{Onceness, m_const, purity};
+use syntax::ast::{Onceness, purity};
 
 pub struct Sub(CombineFields);  // "subtype", "subregion" etc
 
@@ -67,7 +67,7 @@ impl Combine for Sub {
     fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
         debug!("mts(%s <: %s)", a.inf_str(self.infcx), b.inf_str(self.infcx));
 
-        if a.mutbl != b.mutbl && b.mutbl != m_const {
+        if a.mutbl != b.mutbl {
             return Err(ty::terr_mutability);
         }
 
@@ -77,7 +77,7 @@ impl Combine for Sub {
             // (i.e., invariant if mut):
             eq_tys(self, a.ty, b.ty).then(|| Ok(*a))
           }
-          m_imm | m_const => {
+          m_imm => {
             // Otherwise we can be covariant:
             self.tys(a.ty, b.ty).chain(|_t| Ok(*a) )
           }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 0fdcac26ac8..3549323cf08 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -239,7 +239,6 @@ fn mutability_to_str(m: ast::mutability) -> ~str {
     match m {
         ast::m_mutbl => ~"mut ",
         ast::m_imm => ~"",
-        ast::m_const => ~"const "
     }
 }
 
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index d001e2c6970..c192803efff 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -276,7 +276,7 @@ pub mod raw {
             use rt::local::Local;
             use rt::task::Task;
 
-            do Local::borrow::<Task, *()> |task| {
+            do Local::borrow |task: &mut Task| {
                 task.heap.realloc(ptr as *libc::c_void, size) as *()
             }
         }
diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs
index 825d0147c80..a4e18d98f47 100644
--- a/src/libstd/cast.rs
+++ b/src/libstd/cast.rs
@@ -10,6 +10,7 @@
 
 //! Unsafe casting functions
 
+use ptr::RawPtr;
 use sys;
 use unstable::intrinsics;
 
@@ -94,13 +95,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
 
 /// Coerce an immutable reference to be mutable.
 #[inline]
-pub unsafe fn transmute_mut_unsafe<T>(ptr: *const T) -> *mut T {
+pub unsafe fn transmute_mut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *mut T {
     transmute(ptr)
 }
 
 /// Coerce an immutable reference to be mutable.
 #[inline]
-pub unsafe fn transmute_immut_unsafe<T>(ptr: *const T) -> *T {
+pub unsafe fn transmute_immut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *T {
     transmute(ptr)
 }
 
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs
index f9f5b66acb6..a1459b780df 100644
--- a/src/libstd/cell.rs
+++ b/src/libstd/cell.rs
@@ -100,7 +100,7 @@ fn test_basic() {
 #[test]
 #[should_fail]
 fn test_take_empty() {
-    let value_cell = Cell::new_empty::<~int>();
+    let value_cell: Cell<~int> = Cell::new_empty();
     value_cell.take();
 }
 
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs
index 6a6ba12bae3..6b982ec75da 100644
--- a/src/libstd/cleanup.rs
+++ b/src/libstd/cleanup.rs
@@ -11,7 +11,7 @@
 #[doc(hidden)];
 
 use libc::c_void;
-use ptr::{mut_null};
+use ptr::null;
 use unstable::intrinsics::TyDesc;
 use unstable::raw;
 
@@ -37,7 +37,7 @@ unsafe fn each_live_alloc(read_next_before: bool,
     use rt::local_heap;
 
     let mut box = local_heap::live_allocs();
-    while box != mut_null() {
+    while box != null() {
         let next_before = (*box).next;
         let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE;
 
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
index daf8c4afb07..cdce69f7cd7 100644
--- a/src/libstd/fmt/mod.rs
+++ b/src/libstd/fmt/mod.rs
@@ -884,10 +884,17 @@ impl<T> Poly for T {
     }
 }
 
-// n.b. use 'const' to get an implementation for both '*mut' and '*' at the same
-//      time.
-impl<T> Pointer for *const T {
-    fn fmt(t: &*const T, f: &mut Formatter) {
+impl<T> Pointer for *T {
+    fn fmt(t: &*T, f: &mut Formatter) {
+        f.flags |= 1 << (parse::FlagAlternate as uint);
+        do ::uint::to_str_bytes(*t as uint, 16) |buf| {
+            f.pad_integral(buf, "0x", true);
+        }
+    }
+}
+
+impl<T> Pointer for *mut T {
+    fn fmt(t: &*mut T, f: &mut Formatter) {
         f.flags |= 1 << (parse::FlagAlternate as uint);
         do ::uint::to_str_bytes(*t as uint, 16) |buf| {
             f.pad_integral(buf, "0x", true);
@@ -923,8 +930,12 @@ delegate!(float to Float)
 delegate!(f32 to Float)
 delegate!(f64 to Float)
 
-impl<T> Default for *const T {
-    fn fmt(me: &*const T, f: &mut Formatter) { Pointer::fmt(me, f) }
+impl<T> Default for *T {
+    fn fmt(me: &*T, f: &mut Formatter) { Pointer::fmt(me, f) }
+}
+
+impl<T> Default for *mut T {
+    fn fmt(me: &*mut T, f: &mut Formatter) { Pointer::fmt(me, f) }
 }
 
 // If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 50e59cf438d..bcd658ece66 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -869,21 +869,21 @@ mod test_map {
 
     #[test]
     fn test_find_or_insert() {
-        let mut m = HashMap::new::<int, int>();
+        let mut m: HashMap<int,int> = HashMap::new();
         assert_eq!(*m.find_or_insert(1, 2), 2);
         assert_eq!(*m.find_or_insert(1, 3), 2);
     }
 
     #[test]
     fn test_find_or_insert_with() {
-        let mut m = HashMap::new::<int, int>();
+        let mut m: HashMap<int,int> = HashMap::new();
         assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
         assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
     }
 
     #[test]
     fn test_insert_or_update_with() {
-        let mut m = HashMap::new::<int, int>();
+        let mut m: HashMap<int,int> = HashMap::new();
         assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
         assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
     }
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index 1af49ecd208..4af7b3e2425 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -660,7 +660,10 @@ pub trait AdditiveIterator<A> {
 
 impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
     #[inline]
-    fn sum(&mut self) -> A { self.fold(Zero::zero::<A>(), |s, x| s + x) }
+    fn sum(&mut self) -> A {
+        let zero: A = Zero::zero();
+        self.fold(zero, |s, x| s + x)
+    }
 }
 
 /// A trait for iterators over elements whose elements can be multiplied
@@ -685,7 +688,10 @@ pub trait MultiplicativeIterator<A> {
 
 impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
     #[inline]
-    fn product(&mut self) -> A { self.fold(One::one::<A>(), |p, x| p * x) }
+    fn product(&mut self) -> A {
+        let one: A = One::one();
+        self.fold(one, |p, x| p * x)
+    }
 }
 
 /// A trait for iterators over elements which can be compared to one another.
diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs
index 7de55f48317..215067ea729 100644
--- a/src/libstd/logging.rs
+++ b/src/libstd/logging.rs
@@ -59,7 +59,8 @@ fn newsched_log_str(msg: ~str) {
     use rt::local::Local;
 
     unsafe {
-        match Local::try_unsafe_borrow::<Task>() {
+        let optional_task: Option<*mut Task> = Local::try_unsafe_borrow();
+        match optional_task {
             Some(local) => {
                 // Use the available logger
                 (*local).logger.log(Left(msg));
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index a493dba467e..1c59eaf0219 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -182,7 +182,7 @@ impl ApproxEq<f32> for f32 {
 
     #[inline]
     fn approx_eq(&self, other: &f32) -> bool {
-        self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f32, f32>())
+        self.approx_eq_eps(other, &1.0e-6)
     }
 
     #[inline]
@@ -561,11 +561,14 @@ impl Real for f32 {
 
     /// Converts to degrees, assuming the number is in radians
     #[inline]
-    fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
+    fn to_degrees(&self) -> f32 { *self * (180.0f32 / Real::pi()) }
 
     /// Converts to radians, assuming the number is in degrees
     #[inline]
-    fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
+    fn to_radians(&self) -> f32 {
+        let value: f32 = Real::pi();
+        *self * (value / 180.0f32)
+    }
 }
 
 impl Bounded for f32 {
@@ -578,10 +581,10 @@ impl Bounded for f32 {
 
 impl Primitive for f32 {
     #[inline]
-    fn bits() -> uint { 32 }
+    fn bits(_: Option<f32>) -> uint { 32 }
 
     #[inline]
-    fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
+    fn bytes(_: Option<f32>) -> uint { Primitive::bits(Some(0f32)) / 8 }
 }
 
 impl Float for f32 {
@@ -638,25 +641,25 @@ impl Float for f32 {
     }
 
     #[inline]
-    fn mantissa_digits() -> uint { 24 }
+    fn mantissa_digits(_: Option<f32>) -> uint { 24 }
 
     #[inline]
-    fn digits() -> uint { 6 }
+    fn digits(_: Option<f32>) -> uint { 6 }
 
     #[inline]
     fn epsilon() -> f32 { 1.19209290e-07 }
 
     #[inline]
-    fn min_exp() -> int { -125 }
+    fn min_exp(_: Option<f32>) -> int { -125 }
 
     #[inline]
-    fn max_exp() -> int { 128 }
+    fn max_exp(_: Option<f32>) -> int { 128 }
 
     #[inline]
-    fn min_10_exp() -> int { -37 }
+    fn min_10_exp(_: Option<f32>) -> int { -37 }
 
     #[inline]
-    fn max_10_exp() -> int { 38 }
+    fn max_10_exp(_: Option<f32>) -> int { 38 }
 
     /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
     #[inline]
@@ -949,9 +952,11 @@ mod tests {
         assert_eq!(1f32.clamp(&2f32, &4f32), 2f32);
         assert_eq!(8f32.clamp(&2f32, &4f32), 4f32);
         assert_eq!(3f32.clamp(&2f32, &4f32), 3f32);
-        assert!(3f32.clamp(&Float::NaN::<f32>(), &4f32).is_NaN());
-        assert!(3f32.clamp(&2f32, &Float::NaN::<f32>()).is_NaN());
-        assert!(Float::NaN::<f32>().clamp(&2f32, &4f32).is_NaN());
+
+        let nan: f32 = Float::NaN();
+        assert!(3f32.clamp(&nan, &4f32).is_NaN());
+        assert!(3f32.clamp(&2f32, &nan).is_NaN());
+        assert!(nan.clamp(&2f32, &4f32).is_NaN());
     }
 
     #[test]
@@ -1028,9 +1033,13 @@ mod tests {
     fn test_asinh() {
         assert_eq!(0.0f32.asinh(), 0.0f32);
         assert_eq!((-0.0f32).asinh(), -0.0f32);
-        assert_eq!(Float::infinity::<f32>().asinh(), Float::infinity::<f32>());
-        assert_eq!(Float::neg_infinity::<f32>().asinh(), Float::neg_infinity::<f32>());
-        assert!(Float::NaN::<f32>().asinh().is_NaN());
+
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::NaN();
+        assert_eq!(inf.asinh(), inf);
+        assert_eq!(neg_inf.asinh(), neg_inf);
+        assert!(nan.asinh().is_NaN());
         assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
         assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
     }
@@ -1039,9 +1048,13 @@ mod tests {
     fn test_acosh() {
         assert_eq!(1.0f32.acosh(), 0.0f32);
         assert!(0.999f32.acosh().is_NaN());
-        assert_eq!(Float::infinity::<f32>().acosh(), Float::infinity::<f32>());
-        assert!(Float::neg_infinity::<f32>().acosh().is_NaN());
-        assert!(Float::NaN::<f32>().acosh().is_NaN());
+
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::NaN();
+        assert_eq!(inf.acosh(), inf);
+        assert!(neg_inf.acosh().is_NaN());
+        assert!(nan.acosh().is_NaN());
         assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
         assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
     }
@@ -1050,34 +1063,61 @@ mod tests {
     fn test_atanh() {
         assert_eq!(0.0f32.atanh(), 0.0f32);
         assert_eq!((-0.0f32).atanh(), -0.0f32);
-        assert_eq!(1.0f32.atanh(), Float::infinity::<f32>());
-        assert_eq!((-1.0f32).atanh(), Float::neg_infinity::<f32>());
+
+        let inf32: f32 = Float::infinity();
+        let neg_inf32: f32 = Float::neg_infinity();
+        assert_eq!(1.0f32.atanh(), inf32);
+        assert_eq!((-1.0f32).atanh(), neg_inf32);
+
         assert!(2f64.atanh().atanh().is_NaN());
         assert!((-2f64).atanh().atanh().is_NaN());
-        assert!(Float::infinity::<f64>().atanh().is_NaN());
-        assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
-        assert!(Float::NaN::<f32>().atanh().is_NaN());
+
+        let inf64: f32 = Float::infinity();
+        let neg_inf64: f32 = Float::neg_infinity();
+        let nan32: f32 = Float::NaN();
+        assert!(inf64.atanh().is_NaN());
+        assert!(neg_inf64.atanh().is_NaN());
+        assert!(nan32.atanh().is_NaN());
+
         assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
         assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
     }
 
     #[test]
     fn test_real_consts() {
-        assert_approx_eq!(Real::two_pi::<f32>(), 2f32 * Real::pi::<f32>());
-        assert_approx_eq!(Real::frac_pi_2::<f32>(), Real::pi::<f32>() / 2f32);
-        assert_approx_eq!(Real::frac_pi_3::<f32>(), Real::pi::<f32>() / 3f32);
-        assert_approx_eq!(Real::frac_pi_4::<f32>(), Real::pi::<f32>() / 4f32);
-        assert_approx_eq!(Real::frac_pi_6::<f32>(), Real::pi::<f32>() / 6f32);
-        assert_approx_eq!(Real::frac_pi_8::<f32>(), Real::pi::<f32>() / 8f32);
-        assert_approx_eq!(Real::frac_1_pi::<f32>(), 1f32 / Real::pi::<f32>());
-        assert_approx_eq!(Real::frac_2_pi::<f32>(), 2f32 / Real::pi::<f32>());
-        assert_approx_eq!(Real::frac_2_sqrtpi::<f32>(), 2f32 / Real::pi::<f32>().sqrt());
-        assert_approx_eq!(Real::sqrt2::<f32>(), 2f32.sqrt());
-        assert_approx_eq!(Real::frac_1_sqrt2::<f32>(), 1f32 / 2f32.sqrt());
-        assert_approx_eq!(Real::log2_e::<f32>(), Real::e::<f32>().log2());
-        assert_approx_eq!(Real::log10_e::<f32>(), Real::e::<f32>().log10());
-        assert_approx_eq!(Real::ln_2::<f32>(), 2f32.ln());
-        assert_approx_eq!(Real::ln_10::<f32>(), 10f32.ln());
+        let pi: f32 = Real::pi();
+        let two_pi: f32 = Real::two_pi();
+        let frac_pi_2: f32 = Real::frac_pi_2();
+        let frac_pi_3: f32 = Real::frac_pi_3();
+        let frac_pi_4: f32 = Real::frac_pi_4();
+        let frac_pi_6: f32 = Real::frac_pi_6();
+        let frac_pi_8: f32 = Real::frac_pi_8();
+        let frac_1_pi: f32 = Real::frac_1_pi();
+        let frac_2_pi: f32 = Real::frac_2_pi();
+        let frac_2_sqrtpi: f32 = Real::frac_2_sqrtpi();
+        let sqrt2: f32 = Real::sqrt2();
+        let frac_1_sqrt2: f32 = Real::frac_1_sqrt2();
+        let e: f32 = Real::e();
+        let log2_e: f32 = Real::log2_e();
+        let log10_e: f32 = Real::log10_e();
+        let ln_2: f32 = Real::ln_2();
+        let ln_10: f32 = Real::ln_10();
+
+        assert_approx_eq!(two_pi, 2f32 * pi);
+        assert_approx_eq!(frac_pi_2, pi / 2f32);
+        assert_approx_eq!(frac_pi_3, pi / 3f32);
+        assert_approx_eq!(frac_pi_4, pi / 4f32);
+        assert_approx_eq!(frac_pi_6, pi / 6f32);
+        assert_approx_eq!(frac_pi_8, pi / 8f32);
+        assert_approx_eq!(frac_1_pi, 1f32 / pi);
+        assert_approx_eq!(frac_2_pi, 2f32 / pi);
+        assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
+        assert_approx_eq!(sqrt2, 2f32.sqrt());
+        assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
+        assert_approx_eq!(log2_e, e.log2());
+        assert_approx_eq!(log10_e, e.log10());
+        assert_approx_eq!(ln_2, 2f32.ln());
+        assert_approx_eq!(ln_10, 10f32.ln());
     }
 
     #[test]
@@ -1153,17 +1193,23 @@ mod tests {
 
     #[test]
     fn test_primitive() {
-        assert_eq!(Primitive::bits::<f32>(), sys::size_of::<f32>() * 8);
-        assert_eq!(Primitive::bytes::<f32>(), sys::size_of::<f32>());
+        let none: Option<f32> = None;
+        assert_eq!(Primitive::bits(none), sys::size_of::<f32>() * 8);
+        assert_eq!(Primitive::bytes(none), sys::size_of::<f32>());
     }
 
     #[test]
     fn test_is_normal() {
-        assert!(!Float::NaN::<f32>().is_normal());
-        assert!(!Float::infinity::<f32>().is_normal());
-        assert!(!Float::neg_infinity::<f32>().is_normal());
-        assert!(!Zero::zero::<f32>().is_normal());
-        assert!(!Float::neg_zero::<f32>().is_normal());
+        let nan: f32 = Float::NaN();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let zero: f32 = Zero::zero();
+        let neg_zero: f32 = Float::neg_zero();
+        assert!(!nan.is_normal());
+        assert!(!inf.is_normal());
+        assert!(!neg_inf.is_normal());
+        assert!(!zero.is_normal());
+        assert!(!neg_zero.is_normal());
         assert!(1f32.is_normal());
         assert!(1e-37f32.is_normal());
         assert!(!1e-38f32.is_normal());
@@ -1171,11 +1217,16 @@ mod tests {
 
     #[test]
     fn test_classify() {
-        assert_eq!(Float::NaN::<f32>().classify(), FPNaN);
-        assert_eq!(Float::infinity::<f32>().classify(), FPInfinite);
-        assert_eq!(Float::neg_infinity::<f32>().classify(), FPInfinite);
-        assert_eq!(Zero::zero::<f32>().classify(), FPZero);
-        assert_eq!(Float::neg_zero::<f32>().classify(), FPZero);
+        let nan: f32 = Float::NaN();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let zero: f32 = Zero::zero();
+        let neg_zero: f32 = Float::neg_zero();
+        assert_eq!(nan.classify(), FPNaN);
+        assert_eq!(inf.classify(), FPInfinite);
+        assert_eq!(neg_inf.classify(), FPInfinite);
+        assert_eq!(zero.classify(), FPZero);
+        assert_eq!(neg_zero.classify(), FPZero);
         assert_eq!(1f32.classify(), FPNormal);
         assert_eq!(1e-37f32.classify(), FPNormal);
         assert_eq!(1e-38f32.classify(), FPSubnormal);
@@ -1192,11 +1243,13 @@ mod tests {
 
         assert_eq!(Float::ldexp(0f32, -123), 0f32);
         assert_eq!(Float::ldexp(-0f32, -123), -0f32);
-        assert_eq!(Float::ldexp(Float::infinity::<f32>(), -123),
-                   Float::infinity::<f32>());
-        assert_eq!(Float::ldexp(Float::neg_infinity::<f32>(), -123),
-                   Float::neg_infinity::<f32>());
-        assert!(Float::ldexp(Float::NaN::<f32>(), -123).is_NaN());
+
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::NaN();
+        assert_eq!(Float::ldexp(inf, -123), inf);
+        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+        assert!(Float::ldexp(nan, -123).is_NaN());
     }
 
     #[test]
@@ -1214,10 +1267,12 @@ mod tests {
 
         assert_eq!(0f32.frexp(), (0f32, 0));
         assert_eq!((-0f32).frexp(), (-0f32, 0));
-        assert_eq!(match Float::infinity::<f32>().frexp() { (x, _) => x },
-                   Float::infinity::<f32>())
-        assert_eq!(match Float::neg_infinity::<f32>().frexp() { (x, _) => x },
-                   Float::neg_infinity::<f32>())
-        assert!(match Float::NaN::<f32>().frexp() { (x, _) => x.is_NaN() })
+
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::NaN();
+        assert_eq!(match inf.frexp() { (x, _) => x }, inf)
+        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
+        assert!(match nan.frexp() { (x, _) => x.is_NaN() })
     }
 }
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 52e74d969eb..8f5d6473aea 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -205,7 +205,7 @@ impl ApproxEq<f64> for f64 {
 
     #[inline]
     fn approx_eq(&self, other: &f64) -> bool {
-        self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<f64, f64>())
+        self.approx_eq_eps(other, &1.0e-6)
     }
 
     #[inline]
@@ -578,11 +578,14 @@ impl Real for f64 {
 
     /// Converts to degrees, assuming the number is in radians
     #[inline]
-    fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) }
+    fn to_degrees(&self) -> f64 { *self * (180.0f64 / Real::pi()) }
 
     /// Converts to radians, assuming the number is in degrees
     #[inline]
-    fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) }
+    fn to_radians(&self) -> f64 {
+        let value: f64 = Real::pi();
+        *self * (value / 180.0)
+    }
 }
 
 impl RealExt for f64 {
@@ -625,10 +628,10 @@ impl Bounded for f64 {
 
 impl Primitive for f64 {
     #[inline]
-    fn bits() -> uint { 64 }
+    fn bits(_: Option<f64>) -> uint { 64 }
 
     #[inline]
-    fn bytes() -> uint { Primitive::bits::<f64>() / 8 }
+    fn bytes(_: Option<f64>) -> uint { Primitive::bits(Some(0f64)) / 8 }
 }
 
 impl Float for f64 {
@@ -685,25 +688,25 @@ impl Float for f64 {
     }
 
     #[inline]
-    fn mantissa_digits() -> uint { 53 }
+    fn mantissa_digits(_: Option<f64>) -> uint { 53 }
 
     #[inline]
-    fn digits() -> uint { 15 }
+    fn digits(_: Option<f64>) -> uint { 15 }
 
     #[inline]
     fn epsilon() -> f64 { 2.2204460492503131e-16 }
 
     #[inline]
-    fn min_exp() -> int { -1021 }
+    fn min_exp(_: Option<f64>) -> int { -1021 }
 
     #[inline]
-    fn max_exp() -> int { 1024 }
+    fn max_exp(_: Option<f64>) -> int { 1024 }
 
     #[inline]
-    fn min_10_exp() -> int { -307 }
+    fn min_10_exp(_: Option<f64>) -> int { -307 }
 
     #[inline]
-    fn max_10_exp() -> int { 308 }
+    fn max_10_exp(_: Option<f64>) -> int { 308 }
 
     /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
     #[inline]
@@ -983,16 +986,20 @@ mod tests {
     fn test_min() {
         assert_eq!(1f64.min(&2f64), 1f64);
         assert_eq!(2f64.min(&1f64), 1f64);
-        assert!(1f64.min(&Float::NaN::<f64>()).is_NaN());
-        assert!(Float::NaN::<f64>().min(&1f64).is_NaN());
+
+        let nan: f64 = Float::NaN();
+        assert!(1f64.min(&nan).is_NaN());
+        assert!(nan.min(&1f64).is_NaN());
     }
 
     #[test]
     fn test_max() {
         assert_eq!(1f64.max(&2f64), 2f64);
         assert_eq!(2f64.max(&1f64), 2f64);
-        assert!(1f64.max(&Float::NaN::<f64>()).is_NaN());
-        assert!(Float::NaN::<f64>().max(&1f64).is_NaN());
+
+        let nan: f64 = Float::NaN();
+        assert!(1f64.max(&nan).is_NaN());
+        assert!(nan.max(&1f64).is_NaN());
     }
 
     #[test]
@@ -1000,9 +1007,11 @@ mod tests {
         assert_eq!(1f64.clamp(&2f64, &4f64), 2f64);
         assert_eq!(8f64.clamp(&2f64, &4f64), 4f64);
         assert_eq!(3f64.clamp(&2f64, &4f64), 3f64);
-        assert!(3f64.clamp(&Float::NaN::<f64>(), &4f64).is_NaN());
-        assert!(3f64.clamp(&2f64, &Float::NaN::<f64>()).is_NaN());
-        assert!(Float::NaN::<f64>().clamp(&2f64, &4f64).is_NaN());
+
+        let nan: f64 = Float::NaN();
+        assert!(3f64.clamp(&nan, &4f64).is_NaN());
+        assert!(3f64.clamp(&2f64, &nan).is_NaN());
+        assert!(nan.clamp(&2f64, &4f64).is_NaN());
     }
 
     #[test]
@@ -1079,9 +1088,13 @@ mod tests {
     fn test_asinh() {
         assert_eq!(0.0f64.asinh(), 0.0f64);
         assert_eq!((-0.0f64).asinh(), -0.0f64);
-        assert_eq!(Float::infinity::<f64>().asinh(), Float::infinity::<f64>());
-        assert_eq!(Float::neg_infinity::<f64>().asinh(), Float::neg_infinity::<f64>());
-        assert!(Float::NaN::<f64>().asinh().is_NaN());
+
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::NaN();
+        assert_eq!(inf.asinh(), inf);
+        assert_eq!(neg_inf.asinh(), neg_inf);
+        assert!(nan.asinh().is_NaN());
         assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
         assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
     }
@@ -1090,9 +1103,13 @@ mod tests {
     fn test_acosh() {
         assert_eq!(1.0f64.acosh(), 0.0f64);
         assert!(0.999f64.acosh().is_NaN());
-        assert_eq!(Float::infinity::<f64>().acosh(), Float::infinity::<f64>());
-        assert!(Float::neg_infinity::<f64>().acosh().is_NaN());
-        assert!(Float::NaN::<f64>().acosh().is_NaN());
+
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::NaN();
+        assert_eq!(inf.acosh(), inf);
+        assert!(neg_inf.acosh().is_NaN());
+        assert!(nan.acosh().is_NaN());
         assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
         assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
     }
@@ -1101,34 +1118,56 @@ mod tests {
     fn test_atanh() {
         assert_eq!(0.0f64.atanh(), 0.0f64);
         assert_eq!((-0.0f64).atanh(), -0.0f64);
-        assert_eq!(1.0f64.atanh(), Float::infinity::<f64>());
-        assert_eq!((-1.0f64).atanh(), Float::neg_infinity::<f64>());
+
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::NaN();
+        assert_eq!(1.0f64.atanh(), inf);
+        assert_eq!((-1.0f64).atanh(), neg_inf);
         assert!(2f64.atanh().atanh().is_NaN());
         assert!((-2f64).atanh().atanh().is_NaN());
-        assert!(Float::infinity::<f64>().atanh().is_NaN());
-        assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
-        assert!(Float::NaN::<f64>().atanh().is_NaN());
+        assert!(inf.atanh().is_NaN());
+        assert!(neg_inf.atanh().is_NaN());
+        assert!(nan.atanh().is_NaN());
         assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
         assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
     }
 
     #[test]
     fn test_real_consts() {
-        assert_approx_eq!(Real::two_pi::<f64>(), 2.0 * Real::pi::<f64>());
-        assert_approx_eq!(Real::frac_pi_2::<f64>(), Real::pi::<f64>() / 2f64);
-        assert_approx_eq!(Real::frac_pi_3::<f64>(), Real::pi::<f64>() / 3f64);
-        assert_approx_eq!(Real::frac_pi_4::<f64>(), Real::pi::<f64>() / 4f64);
-        assert_approx_eq!(Real::frac_pi_6::<f64>(), Real::pi::<f64>() / 6f64);
-        assert_approx_eq!(Real::frac_pi_8::<f64>(), Real::pi::<f64>() / 8f64);
-        assert_approx_eq!(Real::frac_1_pi::<f64>(), 1f64 / Real::pi::<f64>());
-        assert_approx_eq!(Real::frac_2_pi::<f64>(), 2f64 / Real::pi::<f64>());
-        assert_approx_eq!(Real::frac_2_sqrtpi::<f64>(), 2f64 / Real::pi::<f64>().sqrt());
-        assert_approx_eq!(Real::sqrt2::<f64>(), 2f64.sqrt());
-        assert_approx_eq!(Real::frac_1_sqrt2::<f64>(), 1f64 / 2f64.sqrt());
-        assert_approx_eq!(Real::log2_e::<f64>(), Real::e::<f64>().log2());
-        assert_approx_eq!(Real::log10_e::<f64>(), Real::e::<f64>().log10());
-        assert_approx_eq!(Real::ln_2::<f64>(), 2f64.ln());
-        assert_approx_eq!(Real::ln_10::<f64>(), 10f64.ln());
+        let pi: f64 = Real::pi();
+        let two_pi: f64 = Real::two_pi();
+        let frac_pi_2: f64 = Real::frac_pi_2();
+        let frac_pi_3: f64 = Real::frac_pi_3();
+        let frac_pi_4: f64 = Real::frac_pi_4();
+        let frac_pi_6: f64 = Real::frac_pi_6();
+        let frac_pi_8: f64 = Real::frac_pi_8();
+        let frac_1_pi: f64 = Real::frac_1_pi();
+        let frac_2_pi: f64 = Real::frac_2_pi();
+        let frac_2_sqrtpi: f64 = Real::frac_2_sqrtpi();
+        let sqrt2: f64 = Real::sqrt2();
+        let frac_1_sqrt2: f64 = Real::frac_1_sqrt2();
+        let e: f64 = Real::e();
+        let log2_e: f64 = Real::log2_e();
+        let log10_e: f64 = Real::log10_e();
+        let ln_2: f64 = Real::ln_2();
+        let ln_10: f64 = Real::ln_10();
+
+        assert_approx_eq!(two_pi, 2.0 * pi);
+        assert_approx_eq!(frac_pi_2, pi / 2f64);
+        assert_approx_eq!(frac_pi_3, pi / 3f64);
+        assert_approx_eq!(frac_pi_4, pi / 4f64);
+        assert_approx_eq!(frac_pi_6, pi / 6f64);
+        assert_approx_eq!(frac_pi_8, pi / 8f64);
+        assert_approx_eq!(frac_1_pi, 1f64 / pi);
+        assert_approx_eq!(frac_2_pi, 2f64 / pi);
+        assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
+        assert_approx_eq!(sqrt2, 2f64.sqrt());
+        assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
+        assert_approx_eq!(log2_e, e.log2());
+        assert_approx_eq!(log10_e, e.log10());
+        assert_approx_eq!(ln_2, 2f64.ln());
+        assert_approx_eq!(ln_10, 10f64.ln());
     }
 
     #[test]
@@ -1204,17 +1243,23 @@ mod tests {
 
     #[test]
     fn test_primitive() {
-        assert_eq!(Primitive::bits::<f64>(), sys::size_of::<f64>() * 8);
-        assert_eq!(Primitive::bytes::<f64>(), sys::size_of::<f64>());
+        let none: Option<f64> = None;
+        assert_eq!(Primitive::bits(none), sys::size_of::<f64>() * 8);
+        assert_eq!(Primitive::bytes(none), sys::size_of::<f64>());
     }
 
     #[test]
     fn test_is_normal() {
-        assert!(!Float::NaN::<f64>().is_normal());
-        assert!(!Float::infinity::<f64>().is_normal());
-        assert!(!Float::neg_infinity::<f64>().is_normal());
-        assert!(!Zero::zero::<f64>().is_normal());
-        assert!(!Float::neg_zero::<f64>().is_normal());
+        let nan: f64 = Float::NaN();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let zero: f64 = Zero::zero();
+        let neg_zero: f64 = Float::neg_zero();
+        assert!(!nan.is_normal());
+        assert!(!inf.is_normal());
+        assert!(!neg_inf.is_normal());
+        assert!(!zero.is_normal());
+        assert!(!neg_zero.is_normal());
         assert!(1f64.is_normal());
         assert!(1e-307f64.is_normal());
         assert!(!1e-308f64.is_normal());
@@ -1222,11 +1267,16 @@ mod tests {
 
     #[test]
     fn test_classify() {
-        assert_eq!(Float::NaN::<f64>().classify(), FPNaN);
-        assert_eq!(Float::infinity::<f64>().classify(), FPInfinite);
-        assert_eq!(Float::neg_infinity::<f64>().classify(), FPInfinite);
-        assert_eq!(Zero::zero::<f64>().classify(), FPZero);
-        assert_eq!(Float::neg_zero::<f64>().classify(), FPZero);
+        let nan: f64 = Float::NaN();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let zero: f64 = Zero::zero();
+        let neg_zero: f64 = Float::neg_zero();
+        assert_eq!(nan.classify(), FPNaN);
+        assert_eq!(inf.classify(), FPInfinite);
+        assert_eq!(neg_inf.classify(), FPInfinite);
+        assert_eq!(zero.classify(), FPZero);
+        assert_eq!(neg_zero.classify(), FPZero);
         assert_eq!(1e-307f64.classify(), FPNormal);
         assert_eq!(1e-308f64.classify(), FPSubnormal);
     }
@@ -1242,11 +1292,13 @@ mod tests {
 
         assert_eq!(Float::ldexp(0f64, -123), 0f64);
         assert_eq!(Float::ldexp(-0f64, -123), -0f64);
-        assert_eq!(Float::ldexp(Float::infinity::<f64>(), -123),
-                   Float::infinity::<f64>());
-        assert_eq!(Float::ldexp(Float::neg_infinity::<f64>(), -123),
-                   Float::neg_infinity::<f64>());
-        assert!(Float::ldexp(Float::NaN::<f64>(), -123).is_NaN());
+
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::NaN();
+        assert_eq!(Float::ldexp(inf, -123), inf);
+        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+        assert!(Float::ldexp(nan, -123).is_NaN());
     }
 
     #[test]
@@ -1264,10 +1316,12 @@ mod tests {
 
         assert_eq!(0f64.frexp(), (0f64, 0));
         assert_eq!((-0f64).frexp(), (-0f64, 0));
-        assert_eq!(match Float::infinity::<f64>().frexp() { (x, _) => x },
-                   Float::infinity::<f64>())
-        assert_eq!(match Float::neg_infinity::<f64>().frexp() { (x, _) => x },
-                   Float::neg_infinity::<f64>())
-        assert!(match Float::NaN::<f64>().frexp() { (x, _) => x.is_NaN() })
+
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::NaN();
+        assert_eq!(match inf.frexp() { (x, _) => x }, inf)
+        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
+        assert!(match nan.frexp() { (x, _) => x.is_NaN() })
     }
 }
diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs
index 20c7adbd62c..d019de2468b 100644
--- a/src/libstd/num/float.rs
+++ b/src/libstd/num/float.rs
@@ -342,7 +342,7 @@ impl ApproxEq<float> for float {
 
     #[inline]
     fn approx_eq(&self, other: &float) -> bool {
-        self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<float, float>())
+        self.approx_eq_eps(other, &1.0e-6)
     }
 
     #[inline]
@@ -783,32 +783,56 @@ impl Signed for float {
 
 impl Bounded for float {
     #[inline]
-    fn min_value() -> float { Bounded::min_value::<f64>() as float }
+    fn min_value() -> float {
+        let x: f64 = Bounded::min_value();
+        x as float
+    }
 
     #[inline]
-    fn max_value() -> float { Bounded::max_value::<f64>() as float }
+    fn max_value() -> float {
+        let x: f64 = Bounded::max_value();
+        x as float
+    }
 }
 
 impl Primitive for float {
     #[inline]
-    fn bits() -> uint { Primitive::bits::<f64>() }
+    fn bits(_: Option<float>) -> uint {
+        let bits: uint = Primitive::bits(Some(0f64));
+        bits
+    }
 
     #[inline]
-    fn bytes() -> uint { Primitive::bytes::<f64>() }
+    fn bytes(_: Option<float>) -> uint {
+        let bytes: uint = Primitive::bytes(Some(0f64));
+        bytes
+    }
 }
 
 impl Float for float {
     #[inline]
-    fn NaN() -> float { Float::NaN::<f64>() as float }
+    fn NaN() -> float {
+        let value: f64 = Float::NaN();
+        value as float
+    }
 
     #[inline]
-    fn infinity() -> float { Float::infinity::<f64>() as float }
+    fn infinity() -> float {
+        let value: f64 = Float::infinity();
+        value as float
+    }
 
     #[inline]
-    fn neg_infinity() -> float { Float::neg_infinity::<f64>() as float }
+    fn neg_infinity() -> float {
+        let value: f64 = Float::neg_infinity();
+        value as float
+    }
 
     #[inline]
-    fn neg_zero() -> float { Float::neg_zero::<f64>() as float }
+    fn neg_zero() -> float {
+        let value: f64 = Float::neg_zero();
+        value as float
+    }
 
     /// Returns `true` if the number is NaN
     #[inline]
@@ -832,30 +856,46 @@ impl Float for float {
     fn classify(&self) -> FPCategory { (*self as f64).classify() }
 
     #[inline]
-    fn mantissa_digits() -> uint { Float::mantissa_digits::<f64>() }
+    fn mantissa_digits(_: Option<float>) -> uint {
+        Float::mantissa_digits(Some(0f64))
+    }
 
     #[inline]
-    fn digits() -> uint { Float::digits::<f64>() }
+    fn digits(_: Option<float>) -> uint {
+        Float::digits(Some(0f64))
+    }
 
     #[inline]
-    fn epsilon() -> float { Float::epsilon::<f64>() as float }
+    fn epsilon() -> float {
+        let value: f64 = Float::epsilon();
+        value as float
+    }
 
     #[inline]
-    fn min_exp() -> int { Float::min_exp::<f64>() }
+    fn min_exp(_: Option<float>) -> int {
+        Float::min_exp(Some(0f64))
+    }
 
     #[inline]
-    fn max_exp() -> int { Float::max_exp::<f64>() }
+    fn max_exp(_: Option<float>) -> int {
+        Float::max_exp(Some(0f64))
+    }
 
     #[inline]
-    fn min_10_exp() -> int { Float::min_10_exp::<f64>() }
+    fn min_10_exp(_: Option<float>) -> int {
+        Float::min_10_exp(Some(0f64))
+    }
 
     #[inline]
-    fn max_10_exp() -> int { Float::max_10_exp::<f64>() }
+    fn max_10_exp(_: Option<float>) -> int {
+        Float::max_10_exp(Some(0f64))
+    }
 
     /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
     #[inline]
     fn ldexp(x: float, exp: int) -> float {
-        Float::ldexp(x as f64, exp) as float
+        let value: f64 = Float::ldexp(x as f64, exp);
+        value as float
     }
 
     ///
@@ -937,9 +977,10 @@ mod tests {
         assert_eq!(1f.clamp(&2f, &4f), 2f);
         assert_eq!(8f.clamp(&2f, &4f), 4f);
         assert_eq!(3f.clamp(&2f, &4f), 3f);
-        assert!(3f.clamp(&Float::NaN::<float>(), &4f).is_NaN());
-        assert!(3f.clamp(&2f, &Float::NaN::<float>()).is_NaN());
-        assert!(Float::NaN::<float>().clamp(&2f, &4f).is_NaN());
+        let nan: float = Float::NaN();
+        assert!(3f.clamp(&nan, &4f).is_NaN());
+        assert!(3f.clamp(&2f, &nan).is_NaN());
+        assert!(nan.clamp(&2f, &4f).is_NaN());
     }
 
     #[test]
@@ -1016,9 +1057,13 @@ mod tests {
     fn test_asinh() {
         assert_eq!(0.0f.asinh(), 0.0f);
         assert_eq!((-0.0f).asinh(), -0.0f);
-        assert_eq!(Float::infinity::<float>().asinh(), Float::infinity::<float>());
-        assert_eq!(Float::neg_infinity::<float>().asinh(), Float::neg_infinity::<float>());
-        assert!(Float::NaN::<float>().asinh().is_NaN());
+
+        let inf: float = Float::infinity();
+        let neg_inf: float = Float::neg_infinity();
+        let nan: float = Float::NaN();
+        assert_eq!(inf.asinh(), inf);
+        assert_eq!(neg_inf.asinh(), neg_inf);
+        assert!(nan.asinh().is_NaN());
         assert_approx_eq!(2.0f.asinh(), 1.443635475178810342493276740273105f);
         assert_approx_eq!((-2.0f).asinh(), -1.443635475178810342493276740273105f);
     }
@@ -1027,9 +1072,13 @@ mod tests {
     fn test_acosh() {
         assert_eq!(1.0f.acosh(), 0.0f);
         assert!(0.999f.acosh().is_NaN());
-        assert_eq!(Float::infinity::<float>().acosh(), Float::infinity::<float>());
-        assert!(Float::neg_infinity::<float>().acosh().is_NaN());
-        assert!(Float::NaN::<float>().acosh().is_NaN());
+
+        let inf: float = Float::infinity();
+        let neg_inf: float = Float::neg_infinity();
+        let nan: float = Float::NaN();
+        assert_eq!(inf.acosh(), inf);
+        assert!(neg_inf.acosh().is_NaN());
+        assert!(nan.acosh().is_NaN());
         assert_approx_eq!(2.0f.acosh(), 1.31695789692481670862504634730796844f);
         assert_approx_eq!(3.0f.acosh(), 1.76274717403908605046521864995958461f);
     }
@@ -1038,34 +1087,58 @@ mod tests {
     fn test_atanh() {
         assert_eq!(0.0f.atanh(), 0.0f);
         assert_eq!((-0.0f).atanh(), -0.0f);
-        assert_eq!(1.0f.atanh(), Float::infinity::<float>());
-        assert_eq!((-1.0f).atanh(), Float::neg_infinity::<float>());
+
+        let inf: float = Float::infinity();
+        let neg_inf: float = Float::neg_infinity();
+        let inf64: f64 = Float::infinity();
+        let neg_inf64: f64 = Float::neg_infinity();
+        let nan: float = Float::NaN();
+        assert_eq!(1.0f.atanh(), inf);
+        assert_eq!((-1.0f).atanh(), neg_inf);
         assert!(2f64.atanh().atanh().is_NaN());
         assert!((-2f64).atanh().atanh().is_NaN());
-        assert!(Float::infinity::<f64>().atanh().is_NaN());
-        assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
-        assert!(Float::NaN::<float>().atanh().is_NaN());
+        assert!(inf64.atanh().is_NaN());
+        assert!(neg_inf64.atanh().is_NaN());
+        assert!(nan.atanh().is_NaN());
         assert_approx_eq!(0.5f.atanh(), 0.54930614433405484569762261846126285f);
         assert_approx_eq!((-0.5f).atanh(), -0.54930614433405484569762261846126285f);
     }
 
     #[test]
     fn test_real_consts() {
-        assert_approx_eq!(Real::two_pi::<float>(), 2f * Real::pi::<float>());
-        assert_approx_eq!(Real::frac_pi_2::<float>(), Real::pi::<float>() / 2f);
-        assert_approx_eq!(Real::frac_pi_3::<float>(), Real::pi::<float>() / 3f);
-        assert_approx_eq!(Real::frac_pi_4::<float>(), Real::pi::<float>() / 4f);
-        assert_approx_eq!(Real::frac_pi_6::<float>(), Real::pi::<float>() / 6f);
-        assert_approx_eq!(Real::frac_pi_8::<float>(), Real::pi::<float>() / 8f);
-        assert_approx_eq!(Real::frac_1_pi::<float>(), 1f / Real::pi::<float>());
-        assert_approx_eq!(Real::frac_2_pi::<float>(), 2f / Real::pi::<float>());
-        assert_approx_eq!(Real::frac_2_sqrtpi::<float>(), 2f / Real::pi::<float>().sqrt());
-        assert_approx_eq!(Real::sqrt2::<float>(), 2f.sqrt());
-        assert_approx_eq!(Real::frac_1_sqrt2::<float>(), 1f / 2f.sqrt());
-        assert_approx_eq!(Real::log2_e::<float>(), Real::e::<float>().log2());
-        assert_approx_eq!(Real::log10_e::<float>(), Real::e::<float>().log10());
-        assert_approx_eq!(Real::ln_2::<float>(), 2f.ln());
-        assert_approx_eq!(Real::ln_10::<float>(), 10f.ln());
+        let pi: float = Real::pi();
+        let two_pi: float = Real::two_pi();
+        let frac_pi_2: float = Real::frac_pi_2();
+        let frac_pi_3: float = Real::frac_pi_3();
+        let frac_pi_4: float = Real::frac_pi_4();
+        let frac_pi_6: float = Real::frac_pi_6();
+        let frac_pi_8: float = Real::frac_pi_8();
+        let frac_1_pi: float = Real::frac_1_pi();
+        let frac_2_pi: float = Real::frac_2_pi();
+        let frac_2_sqrtpi: float = Real::frac_2_sqrtpi();
+        let sqrt2: float = Real::sqrt2();
+        let frac_1_sqrt2: float = Real::frac_1_sqrt2();
+        let e: float = Real::e();
+        let log2_e: float = Real::log2_e();
+        let log10_e: float = Real::log10_e();
+        let ln_2: float = Real::ln_2();
+        let ln_10: float = Real::ln_10();
+
+        assert_approx_eq!(two_pi, 2f * pi);
+        assert_approx_eq!(frac_pi_2, pi / 2f);
+        assert_approx_eq!(frac_pi_3, pi / 3f);
+        assert_approx_eq!(frac_pi_4, pi / 4f);
+        assert_approx_eq!(frac_pi_6, pi / 6f);
+        assert_approx_eq!(frac_pi_8, pi / 8f);
+        assert_approx_eq!(frac_1_pi, 1f / pi);
+        assert_approx_eq!(frac_2_pi, 2f / pi);
+        assert_approx_eq!(frac_2_sqrtpi, 2f / pi.sqrt());
+        assert_approx_eq!(sqrt2, 2f.sqrt());
+        assert_approx_eq!(frac_1_sqrt2, 1f / 2f.sqrt());
+        assert_approx_eq!(log2_e, e.log2());
+        assert_approx_eq!(log10_e, e.log10());
+        assert_approx_eq!(ln_2, 2f.ln());
+        assert_approx_eq!(ln_10, 10f.ln());
     }
 
     #[test]
@@ -1141,17 +1214,23 @@ mod tests {
 
     #[test]
     fn test_primitive() {
-        assert_eq!(Primitive::bits::<float>(), sys::size_of::<float>() * 8);
-        assert_eq!(Primitive::bytes::<float>(), sys::size_of::<float>());
+        let none: Option<float> = None;
+        assert_eq!(Primitive::bits(none), sys::size_of::<float>() * 8);
+        assert_eq!(Primitive::bytes(none), sys::size_of::<float>());
     }
 
     #[test]
     fn test_is_normal() {
-        assert!(!Float::NaN::<float>().is_normal());
-        assert!(!Float::infinity::<float>().is_normal());
-        assert!(!Float::neg_infinity::<float>().is_normal());
-        assert!(!Zero::zero::<float>().is_normal());
-        assert!(!Float::neg_zero::<float>().is_normal());
+        let nan: float = Float::NaN();
+        let inf: float = Float::infinity();
+        let neg_inf: float = Float::neg_infinity();
+        let zero: float = Zero::zero();
+        let neg_zero: float = Float::neg_zero();
+        assert!(!nan.is_normal());
+        assert!(!inf.is_normal());
+        assert!(!neg_inf.is_normal());
+        assert!(!zero.is_normal());
+        assert!(!neg_zero.is_normal());
         assert!(1f.is_normal());
         assert!(1e-307f.is_normal());
         assert!(!1e-308f.is_normal());
@@ -1159,11 +1238,16 @@ mod tests {
 
     #[test]
     fn test_classify() {
-        assert_eq!(Float::NaN::<float>().classify(), FPNaN);
-        assert_eq!(Float::infinity::<float>().classify(), FPInfinite);
-        assert_eq!(Float::neg_infinity::<float>().classify(), FPInfinite);
-        assert_eq!(Zero::zero::<float>().classify(), FPZero);
-        assert_eq!(Float::neg_zero::<float>().classify(), FPZero);
+        let nan: float = Float::NaN();
+        let inf: float = Float::infinity();
+        let neg_inf: float = Float::neg_infinity();
+        let zero: float = Zero::zero();
+        let neg_zero: float = Float::neg_zero();
+        assert_eq!(nan.classify(), FPNaN);
+        assert_eq!(inf.classify(), FPInfinite);
+        assert_eq!(neg_inf.classify(), FPInfinite);
+        assert_eq!(zero.classify(), FPZero);
+        assert_eq!(neg_zero.classify(), FPZero);
         assert_eq!(1f.classify(), FPNormal);
         assert_eq!(1e-307f.classify(), FPNormal);
         assert_eq!(1e-308f.classify(), FPSubnormal);
@@ -1180,11 +1264,13 @@ mod tests {
 
         assert_eq!(Float::ldexp(0f, -123), 0f);
         assert_eq!(Float::ldexp(-0f, -123), -0f);
-        assert_eq!(Float::ldexp(Float::infinity::<float>(), -123),
-                   Float::infinity::<float>());
-        assert_eq!(Float::ldexp(Float::neg_infinity::<float>(), -123),
-                   Float::neg_infinity::<float>());
-        assert!(Float::ldexp(Float::NaN::<float>(), -123).is_NaN());
+
+        let inf: float = Float::infinity();
+        let neg_inf: float = Float::neg_infinity();
+        let nan: float = Float::NaN();
+        assert_eq!(Float::ldexp(inf, -123), inf);
+        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+        assert!(Float::ldexp(nan, -123).is_NaN());
     }
 
     #[test]
@@ -1202,11 +1288,13 @@ mod tests {
 
         assert_eq!(0f.frexp(), (0f, 0));
         assert_eq!((-0f).frexp(), (-0f, 0));
-        assert_eq!(match Float::infinity::<float>().frexp() { (x, _) => x },
-                   Float::infinity::<float>())
-        assert_eq!(match Float::neg_infinity::<float>().frexp() { (x, _) => x },
-                   Float::neg_infinity::<float>())
-        assert!(match Float::NaN::<float>().frexp() { (x, _) => x.is_NaN() })
+
+        let inf: float = Float::infinity();
+        let neg_inf: float = Float::neg_infinity();
+        let nan: float = Float::NaN();
+        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
+        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
+        assert!(match nan.frexp() { (x, _) => x.is_NaN() })
     }
 
     #[test]
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index e2218ce2736..6054d557fa5 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -466,10 +466,10 @@ impl Int for $T {}
 
 impl Primitive for $T {
     #[inline]
-    fn bits() -> uint { bits }
+    fn bits(_: Option<$T>) -> uint { bits }
 
     #[inline]
-    fn bytes() -> uint { bits / 8 }
+    fn bytes(_: Option<$T>) -> uint { bits / 8 }
 }
 
 // String conversion functions and impl str -> num
@@ -754,8 +754,9 @@ mod tests {
 
     #[test]
     fn test_primitive() {
-        assert_eq!(Primitive::bits::<$T>(), sys::size_of::<$T>() * 8);
-        assert_eq!(Primitive::bytes::<$T>(), sys::size_of::<$T>());
+        let none: Option<$T> = None;
+        assert_eq!(Primitive::bits(none), sys::size_of::<$T>() * 8);
+        assert_eq!(Primitive::bytes(none), sys::size_of::<$T>());
     }
 
     #[test]
diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs
index fbb8913fbfa..80ab0caac67 100644
--- a/src/libstd/num/num.rs
+++ b/src/libstd/num/num.rs
@@ -272,8 +272,8 @@ pub trait Primitive: Num
                    + Div<Self,Self>
                    + Rem<Self,Self> {
     // FIXME (#5527): These should be associated constants
-    fn bits() -> uint;
-    fn bytes() -> uint;
+    fn bits(unused_self: Option<Self>) -> uint;
+    fn bytes(unused_self: Option<Self>) -> uint;
 }
 
 /// A collection of traits relevant to primitive signed and unsigned integers
@@ -314,13 +314,13 @@ pub trait Float: Real
     fn is_normal(&self) -> bool;
     fn classify(&self) -> FPCategory;
 
-    fn mantissa_digits() -> uint;
-    fn digits() -> uint;
+    fn mantissa_digits(unused_self: Option<Self>) -> uint;
+    fn digits(unused_self: Option<Self>) -> uint;
     fn epsilon() -> Self;
-    fn min_exp() -> int;
-    fn max_exp() -> int;
-    fn min_10_exp() -> int;
-    fn max_10_exp() -> int;
+    fn min_exp(unused_self: Option<Self>) -> int;
+    fn max_exp(unused_self: Option<Self>) -> int;
+    fn min_10_exp(unused_self: Option<Self>) -> int;
+    fn max_10_exp(unused_self: Option<Self>) -> int;
 
     fn ldexp(x: Self, exp: int) -> Self;
     fn frexp(&self) -> (Self, int);
@@ -484,9 +484,9 @@ impl<T: CheckedAdd+CheckedSub+Zero+Ord+Bounded> Saturating for T {
         match self.checked_add(&v) {
             Some(x) => x,
             None => if v >= Zero::zero() {
-                Bounded::max_value::<T>()
+                Bounded::max_value()
             } else {
-                Bounded::min_value::<T>()
+                Bounded::min_value()
             }
         }
     }
@@ -496,9 +496,9 @@ impl<T: CheckedAdd+CheckedSub+Zero+Ord+Bounded> Saturating for T {
         match self.checked_sub(&v) {
             Some(x) => x,
             None => if v >= Zero::zero() {
-                Bounded::min_value::<T>()
+                Bounded::min_value()
             } else {
-                Bounded::max_value::<T>()
+                Bounded::max_value()
             }
         }
     }
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index d81a2756ad8..8ffaed22d01 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -404,10 +404,10 @@ impl ToStrRadix for $T {
 
 impl Primitive for $T {
     #[inline]
-    fn bits() -> uint { bits }
+    fn bits(_: Option<$T>) -> uint { bits }
 
     #[inline]
-    fn bytes() -> uint { bits / 8 }
+    fn bytes(_: Option<$T>) -> uint { bits / 8 }
 }
 
 impl BitCount for $T {
@@ -532,8 +532,9 @@ mod tests {
 
     #[test]
     fn test_primitive() {
-        assert_eq!(Primitive::bits::<$T>(), sys::size_of::<$T>() * 8);
-        assert_eq!(Primitive::bytes::<$T>(), sys::size_of::<$T>());
+        let none: Option<$T> = None;
+        assert_eq!(Primitive::bits(none), sys::size_of::<$T>() * 8);
+        assert_eq!(Primitive::bytes(none), sys::size_of::<$T>());
     }
 
     #[test]
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index e7caf3f23ab..7aae9425302 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -1521,7 +1521,7 @@ impl MemoryMap {
         let r = unsafe {
             libc::mmap(addr, len, prot, flags, fd, offset)
         };
-        if r == libc::MAP_FAILED {
+        if r.equiv(&libc::MAP_FAILED) {
             Err(match errno() as c_int {
                 libc::EACCES => ErrFdNotAvail,
                 libc::EBADF => ErrInvalidFd,
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index 12af303f33f..860b1f4b768 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -12,8 +12,11 @@
 
 use cast;
 use clone::Clone;
+use cmp::Equiv;
 use iterator::{range, Iterator};
 use option::{Option, Some, None};
+#[cfg(stage0)]
+use sys;
 use unstable::intrinsics;
 use util::swap;
 
@@ -24,18 +27,28 @@ use util::swap;
 
 /// Calculate the offset from a pointer
 #[inline]
+#[cfg(stage0)]
 pub fn offset<T>(ptr: *T, count: int) -> *T {
-    unsafe { intrinsics::offset(ptr, count) }
+    (ptr as uint + (count as uint) * sys::size_of::<T>()) as *T
 }
 
-/// Calculate the offset from a const pointer
+/// Calculate the offset from a mut pointer
 #[inline]
-pub fn const_offset<T>(ptr: *const T, count: int) -> *const T {
-    unsafe { intrinsics::offset(ptr as *T, count) }
+#[cfg(stage0)]
+pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
+    (ptr as uint + (count as uint) * sys::size_of::<T>()) as *mut T
+}
+
+/// Calculate the offset from a pointer
+#[inline]
+#[cfg(not(stage0))]
+pub fn offset<T>(ptr: *T, count: int) -> *T {
+    unsafe { intrinsics::offset(ptr, count) }
 }
 
 /// Calculate the offset from a mut pointer
 #[inline]
+#[cfg(not(stage0))]
 pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
     unsafe { intrinsics::offset(ptr as *T, count) as *mut T }
 }
@@ -73,11 +86,11 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
 
 /// Returns true if the pointer is equal to the null pointer.
 #[inline]
-pub fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
+pub fn is_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_null() }
 
 /// Returns true if the pointer is not equal to the null pointer.
 #[inline]
-pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
+pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
 
 /**
  * Copies data from one location to another.
@@ -87,8 +100,10 @@ pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
  */
 #[inline]
 #[cfg(target_word_size = "32")]
-pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    intrinsics::memmove32(dst, src as *T, count as u32);
+pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
+    intrinsics::memmove32(dst,
+                          cast::transmute_immut_unsafe(src),
+                          count as u32);
 }
 
 /**
@@ -99,8 +114,10 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
  */
 #[inline]
 #[cfg(target_word_size = "64")]
-pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    intrinsics::memmove64(dst, src as *T, count as u64);
+pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
+    intrinsics::memmove64(dst,
+                          cast::transmute_immut_unsafe(src),
+                          count as u64);
 }
 
 /**
@@ -111,8 +128,12 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
  */
 #[inline]
 #[cfg(target_word_size = "32")]
-pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    intrinsics::memcpy32(dst, src as *T, count as u32);
+pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
+                                                        src: P,
+                                                        count: uint) {
+    intrinsics::memcpy32(dst,
+                         cast::transmute_immut_unsafe(src),
+                         count as u32);
 }
 
 /**
@@ -123,8 +144,12 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
  */
 #[inline]
 #[cfg(target_word_size = "64")]
-pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
-    intrinsics::memcpy64(dst, src as *T, count as u64);
+pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
+                                                        src: P,
+                                                        count: uint) {
+    intrinsics::memcpy64(dst,
+                         cast::transmute_immut_unsafe(src),
+                         count as u64);
 }
 
 /**
@@ -216,12 +241,6 @@ pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
     thing as *T
 }
 
-/// Transform a const region pointer - &const T - to a const unsafe pointer - *const T.
-#[inline]
-pub fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
-    thing as *const T
-}
-
 /// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T.
 #[inline]
 pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
@@ -269,8 +288,10 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
 
 #[allow(missing_doc)]
 pub trait RawPtr<T> {
+    fn null() -> Self;
     fn is_null(&self) -> bool;
     fn is_not_null(&self) -> bool;
+    fn to_uint(&self) -> uint;
     unsafe fn to_option(&self) -> Option<&T>;
     fn offset(&self, count: int) -> Self;
     unsafe fn offset_inbounds(self, count: int) -> Self;
@@ -278,13 +299,21 @@ pub trait RawPtr<T> {
 
 /// Extension methods for immutable pointers
 impl<T> RawPtr<T> for *T {
+    /// Returns the null pointer.
+    #[inline]
+    fn null() -> *T { null() }
+
     /// Returns true if the pointer is equal to the null pointer.
     #[inline]
-    fn is_null(&self) -> bool { is_null(*self) }
+    fn is_null(&self) -> bool { *self == RawPtr::null() }
 
     /// Returns true if the pointer is not equal to the null pointer.
     #[inline]
-    fn is_not_null(&self) -> bool { is_not_null(*self) }
+    fn is_not_null(&self) -> bool { *self != RawPtr::null() }
+
+    /// Returns the address of this pointer.
+    #[inline]
+    fn to_uint(&self) -> uint { *self as uint }
 
     ///
     /// Returns `None` if the pointer is null, or else returns the value wrapped
@@ -317,13 +346,21 @@ impl<T> RawPtr<T> for *T {
 
 /// Extension methods for mutable pointers
 impl<T> RawPtr<T> for *mut T {
+    /// Returns the null pointer.
+    #[inline]
+    fn null() -> *mut T { mut_null() }
+
     /// Returns true if the pointer is equal to the null pointer.
     #[inline]
-    fn is_null(&self) -> bool { is_null(*self) }
+    fn is_null(&self) -> bool { *self == RawPtr::null() }
 
     /// Returns true if the pointer is not equal to the null pointer.
     #[inline]
-    fn is_not_null(&self) -> bool { is_not_null(*self) }
+    fn is_not_null(&self) -> bool { *self != RawPtr::null() }
+
+    /// Returns the address of this pointer.
+    #[inline]
+    fn to_uint(&self) -> uint { *self as uint }
 
     ///
     /// Returns `None` if the pointer is null, or else returns the value wrapped
@@ -360,13 +397,38 @@ impl<T> RawPtr<T> for *mut T {
 
 // Equality for pointers
 #[cfg(not(test))]
-impl<T> Eq for *const T {
+impl<T> Eq for *T {
+    #[inline]
+    fn eq(&self, other: &*T) -> bool {
+        (*self as uint) == (*other as uint)
+    }
+    #[inline]
+    fn ne(&self, other: &*T) -> bool { !self.eq(other) }
+}
+
+#[cfg(not(test))]
+impl<T> Eq for *mut T {
     #[inline]
-    fn eq(&self, other: &*const T) -> bool {
+    fn eq(&self, other: &*mut T) -> bool {
         (*self as uint) == (*other as uint)
     }
     #[inline]
-    fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
+    fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
+}
+
+// Equivalence for pointers
+#[cfg(not(test))]
+impl<T> Equiv<*mut T> for *T {
+    fn equiv(&self, other: &*mut T) -> bool {
+        self.to_uint() == other.to_uint()
+    }
+}
+
+#[cfg(not(test))]
+impl<T> Equiv<*T> for *mut T {
+    fn equiv(&self, other: &*T) -> bool {
+        self.to_uint() == other.to_uint()
+    }
 }
 
 // Equality for extern "C" fn pointers
@@ -412,21 +474,41 @@ mod externfnpointers {
 
 // Comparison for pointers
 #[cfg(not(test))]
-impl<T> Ord for *const T {
+impl<T> Ord for *T {
+    #[inline]
+    fn lt(&self, other: &*T) -> bool {
+        (*self as uint) < (*other as uint)
+    }
+    #[inline]
+    fn le(&self, other: &*T) -> bool {
+        (*self as uint) <= (*other as uint)
+    }
+    #[inline]
+    fn ge(&self, other: &*T) -> bool {
+        (*self as uint) >= (*other as uint)
+    }
+    #[inline]
+    fn gt(&self, other: &*T) -> bool {
+        (*self as uint) > (*other as uint)
+    }
+}
+
+#[cfg(not(test))]
+impl<T> Ord for *mut T {
     #[inline]
-    fn lt(&self, other: &*const T) -> bool {
+    fn lt(&self, other: &*mut T) -> bool {
         (*self as uint) < (*other as uint)
     }
     #[inline]
-    fn le(&self, other: &*const T) -> bool {
+    fn le(&self, other: &*mut T) -> bool {
         (*self as uint) <= (*other as uint)
     }
     #[inline]
-    fn ge(&self, other: &*const T) -> bool {
+    fn ge(&self, other: &*mut T) -> bool {
         (*self as uint) >= (*other as uint)
     }
     #[inline]
-    fn gt(&self, other: &*const T) -> bool {
+    fn gt(&self, other: &*mut T) -> bool {
         (*self as uint) > (*other as uint)
     }
 }
diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs
index cbac43f27c7..9dc0abdfbd8 100644
--- a/src/libstd/rt/borrowck.rs
+++ b/src/libstd/rt/borrowck.rs
@@ -11,17 +11,18 @@
 use cell::Cell;
 use c_str::ToCStr;
 use cast::transmute;
-use libc::{c_char, size_t, STDERR_FILENO};
-use io;
 use io::{Writer, WriterUtil};
+use io;
+use libc::{c_char, size_t, STDERR_FILENO};
 use option::{Option, None, Some};
-use uint;
+use ptr::RawPtr;
 use rt::env;
 use rt::local::Local;
 use rt::task::Task;
-use str;
 use str::{OwnedStr, StrSlice};
+use str;
 use sys;
+use uint;
 use unstable::raw;
 use vec::ImmutableVector;
 
@@ -37,7 +38,7 @@ pub struct BorrowRecord {
 }
 
 fn try_take_task_borrow_list() -> Option<~[BorrowRecord]> {
-    do Local::borrow::<Task, Option<~[BorrowRecord]>> |task| {
+    do Local::borrow |task: &mut Task| {
         task.borrow_list.take()
     }
 }
@@ -49,7 +50,7 @@ fn swap_task_borrow_list(f: &fn(~[BorrowRecord]) -> ~[BorrowRecord]) {
     };
     let borrows = f(borrows);
     let borrows = Cell::new(borrows);
-    do Local::borrow::<Task, ()> |task| {
+    do Local::borrow |task: &mut Task| {
         task.borrow_list = Some(borrows.take());
     }
 }
@@ -93,12 +94,12 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
 static ENABLE_DEBUG: bool = false;
 
 #[inline]
-unsafe fn debug_borrow<T>(tag: &'static str,
-                          p: *const T,
-                          old_bits: uint,
-                          new_bits: uint,
-                          filename: *c_char,
-                          line: size_t) {
+unsafe fn debug_borrow<T,P:RawPtr<T>>(tag: &'static str,
+                                      p: P,
+                                      old_bits: uint,
+                                      new_bits: uint,
+                                      filename: *c_char,
+                                      line: size_t) {
     //! A useful debugging function that prints a pointer + tag + newline
     //! without allocating memory.
 
@@ -106,15 +107,15 @@ unsafe fn debug_borrow<T>(tag: &'static str,
         debug_borrow_slow(tag, p, old_bits, new_bits, filename, line);
     }
 
-    unsafe fn debug_borrow_slow<T>(tag: &'static str,
-                                   p: *const T,
-                                   old_bits: uint,
-                                   new_bits: uint,
-                                   filename: *c_char,
-                                   line: size_t) {
+    unsafe fn debug_borrow_slow<T,P:RawPtr<T>>(tag: &'static str,
+                                               p: P,
+                                               old_bits: uint,
+                                               new_bits: uint,
+                                               filename: *c_char,
+                                               line: size_t) {
         let dbg = STDERR_FILENO as io::fd_t;
         dbg.write_str(tag);
-        dbg.write_hex(p as uint);
+        dbg.write_hex(p.to_uint());
         dbg.write_str(" ");
         dbg.write_hex(old_bits);
         dbg.write_str(" ");
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index b547d3c9c30..4b1881409f4 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -159,7 +159,7 @@ impl<T> ChanOne<T> {
                         };
                     } else {
                         let recvr = Cell::new(recvr);
-                        do Local::borrow::<Scheduler, ()> |sched| {
+                        do Local::borrow |sched: &mut Scheduler| {
                             sched.enqueue_blocked_task(recvr.take());
                         }
                     }
@@ -199,7 +199,7 @@ impl<T> PortOne<T> {
         if !this.optimistic_check() {
             // No data available yet.
             // Switch to the scheduler to put the ~Task into the Packet state.
-            let sched = Local::take::<Scheduler>();
+            let sched: ~Scheduler = Local::take();
             do sched.deschedule_running_task_and_then |sched, task| {
                 this.block_on(sched, task);
             }
@@ -221,7 +221,7 @@ impl<T> SelectInner for PortOne<T> {
         // The optimistic check is never necessary for correctness. For testing
         // purposes, making it randomly return false simulates a racing sender.
         use rand::{Rand};
-        let actually_check = do Local::borrow::<Scheduler, bool> |sched| {
+        let actually_check = do Local::borrow |sched: &mut Scheduler| {
             Rand::rand(&mut sched.rng)
         };
         if actually_check {
diff --git a/src/libstd/rt/io/file.rs b/src/libstd/rt/io/file.rs
index 65db76d5ef7..f4e9c4d7c11 100644
--- a/src/libstd/rt/io/file.rs
+++ b/src/libstd/rt/io/file.rs
@@ -24,7 +24,7 @@ pub fn open<P: PathLike>(path: &P,
                          access: FileAccess
                         ) -> Option<FileStream> {
     let open_result = unsafe {
-        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
         (*io).fs_open(path, mode, access)
     };
     match open_result {
@@ -43,7 +43,7 @@ pub fn open<P: PathLike>(path: &P,
 /// by `path`.
 pub fn unlink<P: PathLike>(path: &P) {
     let unlink_result = unsafe {
-        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
         (*io).fs_unlink(path)
     };
     match unlink_result {
diff --git a/src/libstd/rt/io/net/ip.rs b/src/libstd/rt/io/net/ip.rs
index 3b3ea80eafa..d1d6b16e2eb 100644
--- a/src/libstd/rt/io/net/ip.rs
+++ b/src/libstd/rt/io/net/ip.rs
@@ -359,7 +359,7 @@ impl FromStr for SocketAddr {
 mod test {
     use super::*;
     use from_str::FromStr;
-    use option::{Some, None};
+    use option::{Option, Some, None};
 
     #[test]
     fn test_from_str_ipv4() {
@@ -368,13 +368,17 @@ mod test {
         assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0"));
 
         // out of range
-        assert_eq!(None, FromStr::from_str::<IpAddr>("256.0.0.1"));
+        let none: Option<IpAddr> = FromStr::from_str("256.0.0.1");
+        assert_eq!(None, none);
         // too short
-        assert_eq!(None, FromStr::from_str::<IpAddr>("255.0.0"));
+        let none: Option<IpAddr> = FromStr::from_str("255.0.0");
+        assert_eq!(None, none);
         // too long
-        assert_eq!(None, FromStr::from_str::<IpAddr>("255.0.0.1.2"));
+        let none: Option<IpAddr> = FromStr::from_str("255.0.0.1.2");
+        assert_eq!(None, none);
         // no number between dots
-        assert_eq!(None, FromStr::from_str::<IpAddr>("255.0..1"));
+        let none: Option<IpAddr> = FromStr::from_str("255.0..1");
+        assert_eq!(None, none);
     }
 
     #[test]
@@ -389,15 +393,20 @@ mod test {
                 FromStr::from_str("2a02:6b8::11:11"));
 
         // too long group
-        assert_eq!(None, FromStr::from_str::<IpAddr>("::00000"));
+        let none: Option<IpAddr> = FromStr::from_str("::00000");
+        assert_eq!(None, none);
         // too short
-        assert_eq!(None, FromStr::from_str::<IpAddr>("1:2:3:4:5:6:7"));
+        let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7");
+        assert_eq!(None, none);
         // too long
-        assert_eq!(None, FromStr::from_str::<IpAddr>("1:2:3:4:5:6:7:8:9"));
+        let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7:8:9");
+        assert_eq!(None, none);
         // triple colon
-        assert_eq!(None, FromStr::from_str::<IpAddr>("1:2:::6:7:8"));
+        let none: Option<IpAddr> = FromStr::from_str("1:2:::6:7:8");
+        assert_eq!(None, none);
         // two double colons
-        assert_eq!(None, FromStr::from_str::<IpAddr>("1:2::6::8"));
+        let none: Option<IpAddr> = FromStr::from_str("1:2::6::8");
+        assert_eq!(None, none);
     }
 
     #[test]
@@ -412,11 +421,15 @@ mod test {
                 FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33"));
 
         // colon after v4
-        assert_eq!(None, FromStr::from_str::<IpAddr>("::127.0.0.1:"));
+        let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:");
+        assert_eq!(None, none);
         // not enought groups
-        assert_eq!(None, FromStr::from_str::<IpAddr>("1.2.3.4.5:127.0.0.1"));
+        let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1");
+        assert_eq!(None, none);
         // too many groups
-        assert_eq!(None, FromStr::from_str::<IpAddr>("1.2.3.4.5:6:7:127.0.0.1"));
+        let none: Option<IpAddr> =
+            FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1");
+        assert_eq!(None, none);
     }
 
     #[test]
@@ -429,13 +442,17 @@ mod test {
                 FromStr::from_str("[::127.0.0.1]:22"));
 
         // without port
-        assert_eq!(None, FromStr::from_str::<SocketAddr>("127.0.0.1"));
+        let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1");
+        assert_eq!(None, none);
         // without port
-        assert_eq!(None, FromStr::from_str::<SocketAddr>("127.0.0.1:"));
+        let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:");
+        assert_eq!(None, none);
         // wrong brackets around v4
-        assert_eq!(None, FromStr::from_str::<SocketAddr>("[127.0.0.1]:22"));
+        let none: Option<SocketAddr> = FromStr::from_str("[127.0.0.1]:22");
+        assert_eq!(None, none);
         // port out of range
-        assert_eq!(None, FromStr::from_str::<SocketAddr>("127.0.0.1:123456"));
+        let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:123456");
+        assert_eq!(None, none);
     }
 
     #[test]
diff --git a/src/libstd/rt/io/net/tcp.rs b/src/libstd/rt/io/net/tcp.rs
index 746fa5668a5..9be5540de48 100644
--- a/src/libstd/rt/io/net/tcp.rs
+++ b/src/libstd/rt/io/net/tcp.rs
@@ -29,7 +29,7 @@ impl TcpStream {
     pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
         let stream = unsafe {
             rtdebug!("borrowing io to connect");
-            let io = Local::unsafe_borrow::<IoFactoryObject>();
+            let io: *mut IoFactoryObject = Local::unsafe_borrow();
             rtdebug!("about to connect");
             (*io).tcp_connect(addr)
         };
@@ -100,7 +100,7 @@ pub struct TcpListener(~RtioTcpListenerObject);
 impl TcpListener {
     pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
         let listener = unsafe {
-            let io = Local::unsafe_borrow::<IoFactoryObject>();
+            let io: *mut IoFactoryObject = Local::unsafe_borrow();
             (*io).tcp_bind(addr)
         };
         match listener {
diff --git a/src/libstd/rt/io/net/udp.rs b/src/libstd/rt/io/net/udp.rs
index 644abcbe145..132ca064515 100644
--- a/src/libstd/rt/io/net/udp.rs
+++ b/src/libstd/rt/io/net/udp.rs
@@ -20,7 +20,10 @@ pub struct UdpSocket(~RtioUdpSocketObject);
 
 impl UdpSocket {
     pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
-        let socket = unsafe { (*Local::unsafe_borrow::<IoFactoryObject>()).udp_bind(addr) };
+        let socket = unsafe {
+            let factory: *mut IoFactoryObject = Local::unsafe_borrow();
+            (*factory).udp_bind(addr)
+        };
         match socket {
             Ok(s) => Some(UdpSocket(s)),
             Err(ioerr) => {
diff --git a/src/libstd/rt/io/timer.rs b/src/libstd/rt/io/timer.rs
index b0ec747800d..7f2d88f994d 100644
--- a/src/libstd/rt/io/timer.rs
+++ b/src/libstd/rt/io/timer.rs
@@ -22,7 +22,7 @@ impl Timer {
     pub fn new() -> Option<Timer> {
         let timer = unsafe {
             rtdebug!("Timer::init: borrowing io to init timer");
-            let io = Local::unsafe_borrow::<IoFactoryObject>();
+            let io: *mut IoFactoryObject = Local::unsafe_borrow();
             rtdebug!("about to init timer");
             (*io).timer_init()
         };
diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs
index 18b7394700f..d4f31879c00 100644
--- a/src/libstd/rt/local.rs
+++ b/src/libstd/rt/local.rs
@@ -19,7 +19,7 @@ use cell::Cell;
 pub trait Local {
     fn put(value: ~Self);
     fn take() -> ~Self;
-    fn exists() -> bool;
+    fn exists(unused_value: Option<Self>) -> bool;
     fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
     unsafe fn unsafe_take() -> ~Self;
     unsafe fn unsafe_borrow() -> *mut Self;
@@ -31,7 +31,7 @@ impl Local for Task {
     fn put(value: ~Task) { unsafe { local_ptr::put(value) } }
     #[inline]
     fn take() -> ~Task { unsafe { local_ptr::take() } }
-    fn exists() -> bool { local_ptr::exists() }
+    fn exists(_: Option<Task>) -> bool { local_ptr::exists() }
     fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
         let mut res: Option<T> = None;
         let res_ptr: *mut Option<T> = &mut res;
@@ -59,7 +59,7 @@ impl Local for Task {
 impl Local for Scheduler {
     fn put(value: ~Scheduler) {
         let value = Cell::new(value);
-        do Local::borrow::<Task,()> |task| {
+        do Local::borrow |task: &mut Task| {
             let task = task;
             task.sched = Some(value.take());
         };
@@ -68,12 +68,12 @@ impl Local for Scheduler {
     fn take() -> ~Scheduler {
         unsafe {
             // XXX: Unsafe for speed
-            let task = Local::unsafe_borrow::<Task>();
+            let task: *mut Task = Local::unsafe_borrow();
             (*task).sched.take_unwrap()
         }
     }
-    fn exists() -> bool {
-        do Local::borrow::<Task,bool> |task| {
+    fn exists(_: Option<Scheduler>) -> bool {
+        do Local::borrow |task: &mut Task| {
             match task.sched {
                 Some(ref _task) => true,
                 None => false
@@ -81,7 +81,7 @@ impl Local for Scheduler {
         }
     }
     fn borrow<T>(f: &fn(&mut Scheduler) -> T) -> T {
-        do Local::borrow::<Task, T> |task| {
+        do Local::borrow |task: &mut Task| {
             match task.sched {
                 Some(~ref mut task) => {
                     f(task)
@@ -94,7 +94,8 @@ impl Local for Scheduler {
     }
     unsafe fn unsafe_take() -> ~Scheduler { rtabort!("unimpl") }
     unsafe fn unsafe_borrow() -> *mut Scheduler {
-        match (*Local::unsafe_borrow::<Task>()).sched {
+        let task: *mut Task = Local::unsafe_borrow();
+        match (*task).sched {
             Some(~ref mut sched) => {
                 let s: *mut Scheduler = &mut *sched;
                 return s;
@@ -105,7 +106,8 @@ impl Local for Scheduler {
         }
     }
     unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> {
-        match Local::try_unsafe_borrow::<Task>() {
+        let task_opt: Option<*mut Task> = Local::try_unsafe_borrow();
+        match task_opt {
             Some(task) => {
                 match (*task).sched {
                     Some(~ref mut sched) => {
@@ -124,15 +126,17 @@ impl Local for Scheduler {
 impl Local for IoFactoryObject {
     fn put(_value: ~IoFactoryObject) { rtabort!("unimpl") }
     fn take() -> ~IoFactoryObject { rtabort!("unimpl") }
-    fn exists() -> bool { rtabort!("unimpl") }
+    fn exists(_: Option<IoFactoryObject>) -> bool { rtabort!("unimpl") }
     fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") }
     unsafe fn unsafe_take() -> ~IoFactoryObject { rtabort!("unimpl") }
     unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
-        let sched = Local::unsafe_borrow::<Scheduler>();
+        let sched: *mut Scheduler = Local::unsafe_borrow();
         let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
         return io;
     }
-    unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> { rtabort!("unimpl") }
+    unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> {
+        rtabort!("unimpl")
+    }
 }
 
 
@@ -198,7 +202,7 @@ mod test {
             let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
             Local::put(task);
 
-            let res = do Local::borrow::<Task,bool> |_task| {
+            let res = do Local::borrow |_task: &mut Task| {
                 true
             };
             assert!(res)
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index aa8c5dd4674..12ec19a1ecc 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -13,7 +13,7 @@
 use libc;
 use libc::{c_void, uintptr_t, size_t};
 use ops::Drop;
-use option::{Some, None};
+use option::{Option, None, Some};
 use rt::local::Local;
 use rt::task::Task;
 use unstable::raw;
@@ -89,7 +89,8 @@ impl Drop for LocalHeap {
 // A little compatibility function
 pub unsafe fn local_free(ptr: *libc::c_char) {
     // XXX: Unsafe borrow for speed. Lame.
-    match Local::try_unsafe_borrow::<Task>() {
+    let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
+    match task_ptr {
         Some(task) => {
             (*task).heap.free(ptr as *libc::c_void);
         }
@@ -98,7 +99,7 @@ pub unsafe fn local_free(ptr: *libc::c_char) {
 }
 
 pub fn live_allocs() -> *raw::Box<()> {
-    let region = do Local::borrow::<Task, *BoxedRegion> |task| {
+    let region = do Local::borrow |task: &mut Task| {
         task.heap.boxed_region
     };
 
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 7436efb5bf5..6dbeb8c0ea9 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -64,7 +64,7 @@ use cell::Cell;
 use clone::Clone;
 use container::Container;
 use iterator::{Iterator, range};
-use option::{Some, None};
+use option::{Option, None, Some};
 use ptr::RawPtr;
 use rt::local::Local;
 use rt::sched::{Scheduler, Shutdown};
@@ -408,7 +408,8 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
 
 pub fn in_sched_context() -> bool {
     unsafe {
-        match Local::try_unsafe_borrow::<Task>() {
+        let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
+        match task_ptr {
             Some(task) => {
                 match (*task).task_type {
                     SchedTask => true,
@@ -422,7 +423,8 @@ pub fn in_sched_context() -> bool {
 
 pub fn in_green_task_context() -> bool {
     unsafe {
-        match Local::try_unsafe_borrow::<Task>() {
+        let task: Option<*mut Task> = Local::try_unsafe_borrow();
+        match task {
             Some(task) => {
                 match (*task).task_type {
                     GreenTask(_) => true,
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 7d59627ba39..b393832871d 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -169,13 +169,13 @@ impl Scheduler {
         // successfully run the input task. Start by running the
         // scheduler. Grab it out of TLS - performing the scheduler
         // action will have given it away.
-        let sched = Local::take::<Scheduler>();
+        let sched: ~Scheduler = Local::take();
 
         rtdebug!("starting scheduler %u", sched.sched_id());
         sched.run();
 
         // Close the idle callback.
-        let mut sched = Local::take::<Scheduler>();
+        let mut sched: ~Scheduler = Local::take();
         sched.idle_callback.get_mut_ref().close();
         // Make one go through the loop to run the close callback.
         sched.run();
@@ -185,7 +185,7 @@ impl Scheduler {
         // cleaning up the memory it uses. As we didn't actually call
         // task.run() on the scheduler task we never get through all
         // the cleanup code it runs.
-        let mut stask = Local::take::<Task>();
+        let mut stask: ~Task = Local::take();
 
         rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id());
 
@@ -212,7 +212,7 @@ impl Scheduler {
             // Our scheduler must be in the task before the event loop
             // is started.
             let self_sched = Cell::new(self_sched);
-            do Local::borrow::<Task,()> |stask| {
+            do Local::borrow |stask: &mut Task| {
                 stask.sched = Some(self_sched.take());
             };
 
@@ -234,7 +234,7 @@ impl Scheduler {
         // already have a scheduler stored in our local task, so we
         // start off by taking it. This is the only path through the
         // scheduler where we get the scheduler this way.
-        let mut sched = Local::take::<Scheduler>();
+        let mut sched: ~Scheduler = Local::take();
 
         // Assume that we need to continue idling unless we reach the
         // end of this function without performing an action.
@@ -522,7 +522,7 @@ impl Scheduler {
         // The current task is grabbed from TLS, not taken as an input.
         // Doing an unsafe_take to avoid writing back a null pointer -
         // We're going to call `put` later to do that.
-        let current_task: ~Task = unsafe { Local::unsafe_take::<Task>() };
+        let current_task: ~Task = unsafe { Local::unsafe_take() };
 
         // Check that the task is not in an atomically() section (e.g.,
         // holding a pthread mutex, which could deadlock the scheduler).
@@ -554,7 +554,8 @@ impl Scheduler {
 
             let current_task: &mut Task = match sched.cleanup_job {
                 Some(CleanupJob { task: ref task, _ }) => {
-                    transmute_mut_region(*transmute_mut_unsafe(task))
+                    let task_ptr: *~Task = task;
+                    transmute_mut_region(*transmute_mut_unsafe(task_ptr))
                 }
                 None => {
                     rtabort!("no cleanup job");
@@ -580,7 +581,7 @@ impl Scheduler {
         // run the cleanup job, as expected by the previously called
         // swap_contexts function.
         unsafe {
-            let task = Local::unsafe_borrow::<Task>();
+            let task: *mut Task = Local::unsafe_borrow();
             (*task).sched.get_mut_ref().run_cleanup_job();
 
             // Must happen after running the cleanup job (of course).
@@ -685,13 +686,13 @@ impl Scheduler {
     }
 
     pub fn run_task(task: ~Task) {
-        let sched = Local::take::<Scheduler>();
+        let sched: ~Scheduler = Local::take();
         sched.process_task(task, Scheduler::switch_task).map_move(Local::put);
     }
 
     pub fn run_task_later(next_task: ~Task) {
         let next_task = Cell::new(next_task);
-        do Local::borrow::<Scheduler,()> |sched| {
+        do Local::borrow |sched: &mut Scheduler| {
             sched.enqueue_task(next_task.take());
         };
     }
@@ -1023,12 +1024,12 @@ mod test {
         // exit before emptying the work queue
         do run_in_newsched_task {
             do spawntask {
-                let sched = Local::take::<Scheduler>();
+                let sched: ~Scheduler = Local::take();
                 do sched.deschedule_running_task_and_then |sched, task| {
                     let task = Cell::new(task);
                     do sched.event_loop.callback_ms(10) {
                         rtdebug!("in callback");
-                        let mut sched = Local::take::<Scheduler>();
+                        let mut sched: ~Scheduler = Local::take();
                         sched.enqueue_blocked_task(task.take());
                         Local::put(sched);
                     }
diff --git a/src/libstd/rt/select.rs b/src/libstd/rt/select.rs
index 19a4948af3c..6cde0a1f216 100644
--- a/src/libstd/rt/select.rs
+++ b/src/libstd/rt/select.rs
@@ -26,3 +26,4 @@ pub trait SelectInner {
 pub trait SelectPortInner<T> {
     fn recv_ready(self) -> Option<T>;
 }
+
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 9c2a6e646d2..b1ab7a6cd5d 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -93,7 +93,7 @@ impl Task {
     pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
         let f = Cell::new(f);
         let home = Cell::new(home);
-        do Local::borrow::<Task, ~Task> |running_task| {
+        do Local::borrow |running_task: &mut Task| {
             let mut sched = running_task.sched.take_unwrap();
             let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
                                                          stack_size,
@@ -111,7 +111,7 @@ impl Task {
     pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
         let f = Cell::new(f);
         let home = Cell::new(home);
-        do Local::borrow::<Task, ~Task> |running_task| {
+        do Local::borrow |running_task: &mut Task| {
             let mut sched = running_task.sched.take_unwrap();
             let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
                                                  stack_size,
@@ -305,7 +305,7 @@ impl Task {
     // Grab both the scheduler and the task from TLS and check if the
     // task is executing on an appropriate scheduler.
     pub fn on_appropriate_sched() -> bool {
-        do Local::borrow::<Task,bool> |task| {
+        do Local::borrow |task: &mut Task| {
             let sched_id = task.sched.get_ref().sched_id();
             let sched_run_anything = task.sched.get_ref().run_anything;
             match task.task_type {
@@ -369,7 +369,7 @@ impl Coroutine {
             unsafe {
 
                 // Again - might work while safe, or it might not.
-                do Local::borrow::<Scheduler,()> |sched| {
+                do Local::borrow |sched: &mut Scheduler| {
                     sched.run_cleanup_job();
                 }
 
@@ -378,7 +378,7 @@ impl Coroutine {
                 // simply unsafe_borrow it to get this reference. We
                 // need to still have the task in TLS though, so we
                 // need to unsafe_borrow.
-                let task = Local::unsafe_borrow::<Task>();
+                let task: *mut Task = Local::unsafe_borrow();
 
                 do (*task).run {
                     // N.B. Removing `start` from the start wrapper
@@ -397,7 +397,7 @@ impl Coroutine {
             }
 
             // We remove the sched from the Task in TLS right now.
-            let sched = Local::take::<Scheduler>();
+            let sched: ~Scheduler = Local::take();
             // ... allowing us to give it away when performing a
             // scheduling operation.
             sched.terminate_current_task()
diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs
index 247893f75de..b8e535e4c7d 100644
--- a/src/libstd/rt/tube.rs
+++ b/src/libstd/rt/tube.rs
@@ -51,7 +51,7 @@ impl<T> Tube<T> {
                 // There's a waiting task. Wake it up
                 rtdebug!("waking blocked tube");
                 let task = (*state).blocked_task.take_unwrap();
-                let sched = Local::take::<Scheduler>();
+                let sched: ~Scheduler = Local::take();
                 sched.resume_blocked_task_immediately(task);
             }
         }
@@ -67,7 +67,7 @@ impl<T> Tube<T> {
                 rtdebug!("blocking on tube recv");
                 assert!(self.p.refcount() > 1); // There better be somebody to wake us up
                 assert!((*state).blocked_task.is_none());
-                let sched = Local::take::<Scheduler>();
+                let sched: ~Scheduler = Local::take();
                 do sched.deschedule_running_task_and_then |_, task| {
                     (*state).blocked_task = Some(task);
                 }
@@ -102,7 +102,7 @@ mod test {
             let mut tube: Tube<int> = Tube::new();
             let tube_clone = tube.clone();
             let tube_clone_cell = Cell::new(tube_clone);
-            let sched = Local::take::<Scheduler>();
+            let sched: ~Scheduler = Local::take();
             do sched.deschedule_running_task_and_then |sched, task| {
                 let mut tube_clone = tube_clone_cell.take();
                 tube_clone.send(1);
@@ -119,7 +119,7 @@ mod test {
             let mut tube: Tube<int> = Tube::new();
             let tube_clone = tube.clone();
             let tube_clone = Cell::new(tube_clone);
-            let sched = Local::take::<Scheduler>();
+            let sched: ~Scheduler = Local::take();
             do sched.deschedule_running_task_and_then |sched, task| {
                 let tube_clone = Cell::new(tube_clone.take());
                 do sched.event_loop.callback {
@@ -143,7 +143,7 @@ mod test {
             let mut tube: Tube<int> = Tube::new();
             let tube_clone = tube.clone();
             let tube_clone = Cell::new(tube_clone);
-            let sched = Local::take::<Scheduler>();
+            let sched: ~Scheduler = Local::take();
             do sched.deschedule_running_task_and_then |sched, task| {
                 callback_send(tube_clone.take(), 0);
 
@@ -151,7 +151,7 @@ mod test {
                     if i == 100 { return; }
 
                     let tube = Cell::new(Cell::new(tube));
-                    do Local::borrow::<Scheduler, ()> |sched| {
+                    do Local::borrow |sched: &mut Scheduler| {
                         let tube = tube.take();
                         do sched.event_loop.callback {
                             let mut tube = tube.take();
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index 6e79a78e061..e620ab274b1 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -57,7 +57,7 @@ trait HomingIO {
         let old_home = Cell::new_empty();
         let old_home_ptr = &old_home;
         do task::unkillable { // FIXME(#8674)
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             do scheduler.deschedule_running_task_and_then |_, task| {
                 // get the old home first
                 do task.wake().map_move |mut task| {
@@ -72,7 +72,7 @@ trait HomingIO {
 
         // unhome home
         do task::unkillable { // FIXME(#8674)
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             do scheduler.deschedule_running_task_and_then |scheduler, task| {
                 do task.wake().map_move |mut task| {
                     task.give_home(old_home.take());
@@ -92,7 +92,7 @@ trait HomingIO {
             // go home
             let old_home = Cell::new_empty();
             let old_home_ptr = &old_home;
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             do scheduler.deschedule_running_task_and_then |_, task| {
                 // get the old home first
                 do task.wake().map_move |mut task| {
@@ -102,11 +102,11 @@ trait HomingIO {
             }
 
             // do IO
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             let a = io_sched(self, scheduler);
 
             // unhome home
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             do scheduler.deschedule_running_task_and_then |scheduler, task| {
                 do task.wake().map_move |mut task| {
                     task.give_home(old_home.take());
@@ -122,7 +122,7 @@ trait HomingIO {
 
 // get a handle for the current scheduler
 macro_rules! get_handle_to_current_scheduler(
-    () => (do Local::borrow::<Scheduler, SchedHandle> |sched| { sched.make_handle() })
+    () => (do Local::borrow |sched: &mut Scheduler| { sched.make_handle() })
 )
 
 enum SocketNameKind {
@@ -375,7 +375,7 @@ mod test_remote {
             let mut tube = Tube::new();
             let tube_clone = tube.clone();
             let remote_cell = Cell::new_empty();
-            do Local::borrow::<Scheduler, ()>() |sched| {
+            do Local::borrow |sched: &mut Scheduler| {
                 let tube_clone = tube_clone.clone();
                 let tube_clone_cell = Cell::new(tube_clone);
                 let remote = do sched.event_loop.remote_callback {
@@ -416,7 +416,7 @@ impl IoFactory for UvIoFactory {
 
         // Block this task and take ownership, switch to scheduler context
         do task::unkillable { // FIXME(#8674)
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             do scheduler.deschedule_running_task_and_then |_, task| {
 
                 let mut tcp = TcpWatcher::new(self.uv_loop());
@@ -434,7 +434,7 @@ impl IoFactory for UvIoFactory {
                             unsafe { (*result_cell_ptr).put_back(res); }
 
                             // Context switch
-                            let scheduler = Local::take::<Scheduler>();
+                            let scheduler: ~Scheduler = Local::take();
                             scheduler.resume_blocked_task_immediately(task_cell.take());
                         }
                         Some(_) => {
@@ -442,7 +442,7 @@ impl IoFactory for UvIoFactory {
                             do stream.close {
                                 let res = Err(uv_error_to_io_error(status.unwrap()));
                                 unsafe { (*result_cell_ptr).put_back(res); }
-                                let scheduler = Local::take::<Scheduler>();
+                                let scheduler: ~Scheduler = Local::take();
                                 scheduler.resume_blocked_task_immediately(task_cell.take());
                             }
                         }
@@ -464,11 +464,11 @@ impl IoFactory for UvIoFactory {
             }
             Err(uverr) => {
                 do task::unkillable { // FIXME(#8674)
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     do scheduler.deschedule_running_task_and_then |_, task| {
                         let task_cell = Cell::new(task);
                         do watcher.as_stream().close {
-                            let scheduler = Local::take::<Scheduler>();
+                            let scheduler: ~Scheduler = Local::take();
                             scheduler.resume_blocked_task_immediately(task_cell.take());
                         }
                     }
@@ -487,11 +487,11 @@ impl IoFactory for UvIoFactory {
             }
             Err(uverr) => {
                 do task::unkillable { // FIXME(#8674)
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     do scheduler.deschedule_running_task_and_then |_, task| {
                         let task_cell = Cell::new(task);
                         do watcher.close {
-                            let scheduler = Local::take::<Scheduler>();
+                            let scheduler: ~Scheduler = Local::take();
                             scheduler.resume_blocked_task_immediately(task_cell.take());
                         }
                     }
@@ -539,7 +539,7 @@ impl IoFactory for UvIoFactory {
                                            IoError>> = &result_cell;
         let path_cell = Cell::new(path);
         do task::unkillable { // FIXME(#8674)
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 let path = path_cell.take();
@@ -553,12 +553,12 @@ impl IoFactory for UvIoFactory {
                             loop_, fd, true, home) as ~RtioFileStream;
                         let res = Ok(fs);
                         unsafe { (*result_cell_ptr).put_back(res); }
-                        let scheduler = Local::take::<Scheduler>();
+                        let scheduler: ~Scheduler = Local::take();
                         scheduler.resume_blocked_task_immediately(task_cell.take());
                     } else {
                         let res = Err(uv_error_to_io_error(err.unwrap()));
                         unsafe { (*result_cell_ptr).put_back(res); }
-                        let scheduler = Local::take::<Scheduler>();
+                        let scheduler: ~Scheduler = Local::take();
                         scheduler.resume_blocked_task_immediately(task_cell.take());
                     }
                 };
@@ -573,7 +573,7 @@ impl IoFactory for UvIoFactory {
         let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
         let path_cell = Cell::new(path);
         do task::unkillable { // FIXME(#8674)
-            let scheduler = Local::take::<Scheduler>();
+            let scheduler: ~Scheduler = Local::take();
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 let path = path_cell.take();
@@ -583,7 +583,7 @@ impl IoFactory for UvIoFactory {
                         Some(err) => Err(uv_error_to_io_error(err))
                     };
                     unsafe { (*result_cell_ptr).put_back(res); }
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 };
             };
@@ -625,7 +625,7 @@ impl Drop for UvTcpListener {
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 do self_.watcher().as_stream().close {
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -717,7 +717,7 @@ impl Drop for UvTcpStream {
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 do self_.watcher.as_stream().close {
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -765,7 +765,7 @@ impl RtioTcpStream for UvTcpStream {
 
                     unsafe { (*result_cell_ptr).put_back(result); }
 
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -793,7 +793,7 @@ impl RtioTcpStream for UvTcpStream {
 
                     unsafe { (*result_cell_ptr).put_back(result); }
 
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -876,7 +876,7 @@ impl Drop for UvUdpSocket {
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 do self_.watcher.close {
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -917,7 +917,7 @@ impl RtioUdpSocket for UvUdpSocket {
 
                     unsafe { (*result_cell_ptr).put_back(result); }
 
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -944,7 +944,7 @@ impl RtioUdpSocket for UvUdpSocket {
 
                     unsafe { (*result_cell_ptr).put_back(result); }
 
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -1094,7 +1094,7 @@ impl Drop for UvTimer {
             do scheduler.deschedule_running_task_and_then |_, task| {
                 let task_cell = Cell::new(task);
                 do self_.watcher.close {
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -1110,7 +1110,7 @@ impl RtioTimer for UvTimer {
                 let task_cell = Cell::new(task);
                 do self_.watcher.start(msecs, 0) |_, status| {
                     assert!(status.is_none());
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 }
             }
@@ -1154,7 +1154,7 @@ impl UvFileStream {
                         Some(err) => Err(uv_error_to_io_error(err))
                     };
                     unsafe { (*result_cell_ptr).put_back(res); }
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 };
             };
@@ -1175,7 +1175,7 @@ impl UvFileStream {
                         Some(err) => Err(uv_error_to_io_error(err))
                     };
                     unsafe { (*result_cell_ptr).put_back(res); }
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
                 };
             };
@@ -1208,7 +1208,7 @@ impl Drop for UvFileStream {
                 do scheduler.deschedule_running_task_and_then |_, task| {
                     let task_cell = Cell::new(task);
                     do self_.fd.close(&self.loop_) |_,_| {
-                        let scheduler = Local::take::<Scheduler>();
+                        let scheduler: ~Scheduler = Local::take();
                         scheduler.resume_blocked_task_immediately(task_cell.take());
                     };
                 };
@@ -1254,7 +1254,7 @@ impl RtioFileStream for UvFileStream {
 fn test_simple_io_no_connect() {
     do run_in_newsched_task {
         unsafe {
-            let io = Local::unsafe_borrow::<IoFactoryObject>();
+            let io: *mut IoFactoryObject = Local::unsafe_borrow();
             let addr = next_test_ip4();
             let maybe_chan = (*io).tcp_connect(addr);
             assert!(maybe_chan.is_err());
@@ -1266,7 +1266,7 @@ fn test_simple_io_no_connect() {
 fn test_simple_udp_io_bind_only() {
     do run_in_newsched_task {
         unsafe {
-            let io = Local::unsafe_borrow::<IoFactoryObject>();
+            let io: *mut IoFactoryObject = Local::unsafe_borrow();
             let addr = next_test_ip4();
             let maybe_socket = (*io).udp_bind(addr);
             assert!(maybe_socket.is_ok());
@@ -1303,7 +1303,9 @@ fn test_simple_homed_udp_io_bind_then_move_task_then_home_and_close() {
         };
 
         let test_function: ~fn() = || {
-            let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() };
+            let io: *mut IoFactoryObject = unsafe {
+                Local::unsafe_borrow()
+            };
             let addr = next_test_ip4();
             let maybe_socket = unsafe { (*io).udp_bind(addr) };
             // this socket is bound to this event loop
@@ -1311,7 +1313,7 @@ fn test_simple_homed_udp_io_bind_then_move_task_then_home_and_close() {
 
             // block self on sched1
             do task::unkillable { // FIXME(#8674)
-                let scheduler = Local::take::<Scheduler>();
+                let scheduler: ~Scheduler = Local::take();
                 do scheduler.deschedule_running_task_and_then |_, task| {
                     // unblock task
                     do task.wake().map_move |task| {
@@ -1377,7 +1379,9 @@ fn test_simple_homed_udp_io_bind_then_move_handle_then_home_and_close() {
         let chan = Cell::new(chan);
 
         let body1: ~fn() = || {
-            let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() };
+            let io: *mut IoFactoryObject = unsafe {
+                Local::unsafe_borrow()
+            };
             let addr = next_test_ip4();
             let socket = unsafe { (*io).udp_bind(addr) };
             assert!(socket.is_ok());
@@ -1430,7 +1434,7 @@ fn test_simple_tcp_server_and_client() {
         // Start the server first so it's listening when we connect
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut listener = (*io).tcp_bind(addr).unwrap();
                 let mut stream = listener.accept().unwrap();
                 let mut buf = [0, .. 2048];
@@ -1445,7 +1449,7 @@ fn test_simple_tcp_server_and_client() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut stream = (*io).tcp_connect(addr).unwrap();
                 stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
             }
@@ -1489,7 +1493,9 @@ fn test_simple_tcp_server_and_client_on_diff_threads() {
         };
 
         let server_fn: ~fn() = || {
-            let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() };
+            let io: *mut IoFactoryObject = unsafe {
+                Local::unsafe_borrow()
+            };
             let mut listener = unsafe { (*io).tcp_bind(server_addr).unwrap() };
             let mut stream = listener.accept().unwrap();
             let mut buf = [0, .. 2048];
@@ -1501,7 +1507,9 @@ fn test_simple_tcp_server_and_client_on_diff_threads() {
         };
 
         let client_fn: ~fn() = || {
-            let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() };
+            let io: *mut IoFactoryObject = unsafe {
+                Local::unsafe_borrow()
+            };
             let mut stream = unsafe { (*io).tcp_connect(client_addr) };
             while stream.is_err() {
                 stream = unsafe { (*io).tcp_connect(client_addr) };
@@ -1540,7 +1548,7 @@ fn test_simple_udp_server_and_client() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut server_socket = (*io).udp_bind(server_addr).unwrap();
                 let mut buf = [0, .. 2048];
                 let (nread,src) = server_socket.recvfrom(buf).unwrap();
@@ -1555,7 +1563,7 @@ fn test_simple_udp_server_and_client() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut client_socket = (*io).udp_bind(client_addr).unwrap();
                 client_socket.sendto([0, 1, 2, 3, 4, 5, 6, 7], server_addr);
             }
@@ -1569,7 +1577,7 @@ fn test_read_and_block() {
         let addr = next_test_ip4();
 
         do spawntask {
-            let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() };
+            let io: *mut IoFactoryObject = unsafe { Local::unsafe_borrow() };
             let mut listener = unsafe { (*io).tcp_bind(addr).unwrap() };
             let mut stream = listener.accept().unwrap();
             let mut buf = [0, .. 2048];
@@ -1588,7 +1596,7 @@ fn test_read_and_block() {
                 reads += 1;
 
                 do task::unkillable { // FIXME(#8674)
-                    let scheduler = Local::take::<Scheduler>();
+                    let scheduler: ~Scheduler = Local::take();
                     // Yield to the other task in hopes that it
                     // will trigger a read callback while we are
                     // not ready for it
@@ -1605,7 +1613,7 @@ fn test_read_and_block() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut stream = (*io).tcp_connect(addr).unwrap();
                 stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
                 stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
@@ -1625,7 +1633,7 @@ fn test_read_read_read() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut listener = (*io).tcp_bind(addr).unwrap();
                 let mut stream = listener.accept().unwrap();
                 let buf = [1, .. 2048];
@@ -1639,7 +1647,7 @@ fn test_read_read_read() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut stream = (*io).tcp_connect(addr).unwrap();
                 let mut buf = [0, .. 2048];
                 let mut total_bytes_read = 0;
@@ -1665,7 +1673,7 @@ fn test_udp_twice() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut client = (*io).udp_bind(client_addr).unwrap();
                 assert!(client.sendto([1], server_addr).is_ok());
                 assert!(client.sendto([2], server_addr).is_ok());
@@ -1674,7 +1682,7 @@ fn test_udp_twice() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut server = (*io).udp_bind(server_addr).unwrap();
                 let mut buf1 = [0];
                 let mut buf2 = [0];
@@ -1702,7 +1710,7 @@ fn test_udp_many_read() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut server_out = (*io).udp_bind(server_out_addr).unwrap();
                 let mut server_in = (*io).udp_bind(server_in_addr).unwrap();
                 let msg = [1, .. 2048];
@@ -1725,7 +1733,7 @@ fn test_udp_many_read() {
 
         do spawntask {
             unsafe {
-                let io = Local::unsafe_borrow::<IoFactoryObject>();
+                let io: *mut IoFactoryObject = Local::unsafe_borrow();
                 let mut client_out = (*io).udp_bind(client_out_addr).unwrap();
                 let mut client_in = (*io).udp_bind(client_in_addr).unwrap();
                 let mut total_bytes_recv = 0;
@@ -1754,7 +1762,7 @@ fn test_udp_many_read() {
 fn test_timer_sleep_simple() {
     do run_in_newsched_task {
         unsafe {
-            let io = Local::unsafe_borrow::<IoFactoryObject>();
+            let io: *mut IoFactoryObject = Local::unsafe_borrow();
             let timer = (*io).timer_init();
             do timer.map_move |mut t| { t.sleep(1) };
         }
@@ -1768,7 +1776,7 @@ fn file_test_uvio_full_simple_impl() {
     use path::Path;
     use rt::io::{Open, Create, ReadWrite, Read};
     unsafe {
-        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
         let write_val = "hello uvio!";
         let path = "./tmp/file_test_uvio_full.txt";
         {
@@ -1802,7 +1810,7 @@ fn uvio_naive_print(input: &str) {
     use str::StrSlice;
     unsafe {
         use libc::{STDOUT_FILENO};
-        let io = Local::unsafe_borrow::<IoFactoryObject>();
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
         {
             let mut fd = (*io).fs_from_raw_fd(STDOUT_FILENO, false);
             let write_buf = input.as_bytes();
diff --git a/src/libstd/select.rs b/src/libstd/select.rs
index 531d55f6043..f121158d4c5 100644
--- a/src/libstd/select.rs
+++ b/src/libstd/select.rs
@@ -60,7 +60,7 @@ pub fn select<A: Select>(ports: &mut [A]) -> uint {
 
     do (|| {
         let c = Cell::new(c.take());
-        let sched = Local::take::<Scheduler>();
+        let sched: ~Scheduler = Local::take();
         do sched.deschedule_running_task_and_then |sched, task| {
             let task_handles = task.make_selectable(ports.len());
 
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs
index bfb9bee7802..cb0753fb2e5 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -143,7 +143,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
         if in_green_task_context() {
             // XXX: Logging doesn't work here - the check to call the log
             // function never passes - so calling the log function directly.
-            do Local::borrow::<Task, ()> |task| {
+            do Local::borrow |task: &mut Task| {
                 let msg = match task.name {
                     Some(ref name) =>
                     fmt!("task '%s' failed at '%s', %s:%i",
@@ -160,7 +160,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
                      msg, file, line as int);
         }
 
-        let task = Local::unsafe_borrow::<Task>();
+        let task: *mut Task = Local::unsafe_borrow();
         if (*task).unwinder.unwinding {
             rtabort!("unwinding again");
         }
diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs
index 8132bfe5377..2c2dfd8f689 100644
--- a/src/libstd/task/local_data_priv.rs
+++ b/src/libstd/task/local_data_priv.rs
@@ -28,7 +28,7 @@ impl Handle {
     pub fn new() -> Handle {
         use rt::local::Local;
         unsafe {
-            let task = Local::unsafe_borrow::<Task>();
+            let task: *mut Task = Local::unsafe_borrow();
             NewHandle(&mut (*task).storage)
         }
     }
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index f872c2614b9..c0b331c52ee 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -526,7 +526,7 @@ pub fn with_task_name<U>(blk: &fn(Option<&str>) -> U) -> U {
     use rt::task::Task;
 
     if in_green_task_context() {
-        do Local::borrow::<Task, U> |task| {
+        do Local::borrow |task: &mut Task| {
             match task.name {
                 Some(ref name) => blk(Some(name.as_slice())),
                 None => blk(None)
@@ -545,7 +545,7 @@ pub fn deschedule() {
 
     // FIXME #6842: What does yield really mean in newsched?
     // FIXME(#7544): Optimize this, since we know we won't block.
-    let sched = Local::take::<Scheduler>();
+    let sched: ~Scheduler = Local::take();
     do sched.deschedule_running_task_and_then |sched, task| {
         sched.enqueue_blocked_task(task);
     }
@@ -556,7 +556,7 @@ pub fn failing() -> bool {
 
     use rt::task::Task;
 
-    do Local::borrow::<Task, bool> |local| {
+    do Local::borrow |local: &mut Task| {
         local.unwinder.unwinding
     }
 }
@@ -582,7 +582,7 @@ pub fn unkillable<U>(f: &fn() -> U) -> U {
     unsafe {
         if in_green_task_context() {
             // The inhibits/allows might fail and need to borrow the task.
-            let t = Local::unsafe_borrow::<Task>();
+            let t: *mut Task = Local::unsafe_borrow();
             do (|| {
                 (*t).death.inhibit_kill((*t).unwinder.unwinding);
                 f()
@@ -616,7 +616,7 @@ pub fn rekillable<U>(f: &fn() -> U) -> U {
 
     unsafe {
         if in_green_task_context() {
-            let t = Local::unsafe_borrow::<Task>();
+            let t: *mut Task = Local::unsafe_borrow();
             do (|| {
                 (*t).death.allow_kill((*t).unwinder.unwinding);
                 f()
@@ -1032,7 +1032,7 @@ fn test_try_fail() {
 
 #[cfg(test)]
 fn get_sched_id() -> int {
-    do Local::borrow::<::rt::sched::Scheduler, int> |sched| {
+    do Local::borrow |sched: &mut ::rt::sched::Scheduler| {
         sched.sched_id() as int
     }
 }
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 980141d29c3..c3a3dc56ce2 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -449,7 +449,7 @@ impl RuntimeGlue {
     fn kill_task(mut handle: KillHandle) {
         do handle.kill().map_move |killed_task| {
             let killed_task = Cell::new(killed_task);
-            do Local::borrow::<Scheduler, ()> |sched| {
+            do Local::borrow |sched: &mut Scheduler| {
                 sched.enqueue_task(killed_task.take());
             }
         };
@@ -460,7 +460,7 @@ impl RuntimeGlue {
         unsafe {
             // Can't use safe borrow, because the taskgroup destructor needs to
             // access the scheduler again to send kill signals to other tasks.
-            let me = Local::unsafe_borrow::<Task>();
+            let me: *mut Task = Local::unsafe_borrow();
             blk((*me).death.kill_handle.get_ref(), (*me).unwinder.unwinding)
         }
     }
@@ -470,7 +470,7 @@ impl RuntimeGlue {
         unsafe {
             // Can't use safe borrow, because creating new hashmaps for the
             // tasksets requires an rng, which needs to borrow the sched.
-            let me = Local::unsafe_borrow::<Task>();
+            let me: *mut Task = Local::unsafe_borrow();
             blk(match (*me).taskgroup {
                 None => {
                     // First task in its (unlinked/unsupervised) taskgroup.
@@ -574,7 +574,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
         // If child data is 'None', the enlist is vacuously successful.
         let enlist_success = do child_data.take().map_move_default(true) |child_data| {
             let child_data = Cell::new(child_data); // :(
-            do Local::borrow::<Task, bool> |me| {
+            do Local::borrow |me: &mut Task| {
                 let (child_tg, ancestors) = child_data.take();
                 let mut ancestors = ancestors;
                 let handle = me.death.kill_handle.get_ref();
@@ -608,7 +608,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
     } else {
         unsafe {
             // Creating a 1:1 task:thread ...
-            let sched = Local::unsafe_borrow::<Scheduler>();
+            let sched: *mut Scheduler = Local::unsafe_borrow();
             let sched_handle = (*sched).make_handle();
 
             // Since this is a 1:1 scheduler we create a queue not in
diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs
index 198c09964bb..01f57c231da 100644
--- a/src/libstd/to_bytes.rs
+++ b/src/libstd/to_bytes.rs
@@ -343,7 +343,14 @@ impl<A:IterBytes> IterBytes for ~A {
 
 // NB: raw-pointer IterBytes does _not_ dereference
 // to the target; it just gives you the pointer-bytes.
-impl<A> IterBytes for *const A {
+impl<A> IterBytes for *A {
+    #[inline]
+    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+        (*self as uint).iter_bytes(lsb0, f)
+    }
+}
+
+impl<A> IterBytes for *mut A {
     #[inline]
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         (*self as uint).iter_bytes(lsb0, f)
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 12073a1f4f0..5d9ca6202e2 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -176,7 +176,7 @@ macro_rules! tuple_impls {
                 impl<$($T:Zero),+> Zero for ($($T,)+) {
                     #[inline]
                     fn zero() -> ($($T,)+) {
-                        ($(Zero::zero::<$T>(),)+)
+                        ($({ let x: $T = Zero::zero(); x},)+)
                     }
                     #[inline]
                     fn is_zero(&self) -> bool {
diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs
index f286235ca0e..f9380e7ad12 100644
--- a/src/libstd/unstable/atomics.rs
+++ b/src/libstd/unstable/atomics.rs
@@ -538,7 +538,8 @@ mod test {
 
     #[test]
     fn option_empty() {
-        assert!(AtomicOption::empty::<()>().is_empty(SeqCst));
+        let mut option: AtomicOption<()> = AtomicOption::empty();
+        assert!(option.is_empty(SeqCst));
     }
 
     #[test]
diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs
index e47a3c49f96..1d839b55195 100644
--- a/src/libstd/unstable/lang.rs
+++ b/src/libstd/unstable/lang.rs
@@ -13,7 +13,7 @@
 use c_str::ToCStr;
 use cast::transmute;
 use libc::{c_char, c_void, size_t, uintptr_t};
-use option::{Some, None};
+use option::{Option, None, Some};
 use sys;
 use rt::task::Task;
 use rt::local::Local;
@@ -37,7 +37,8 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
 #[lang="malloc"]
 pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
     // XXX: Unsafe borrow for speed. Lame.
-    match Local::try_unsafe_borrow::<Task>() {
+    let task: Option<*mut Task> = Local::try_unsafe_borrow();
+    match task {
         Some(task) => {
             (*task).heap.alloc(td as *c_void, size as uint) as *c_char
         }
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index cf8ec968e92..8d1545ea2b4 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -279,7 +279,8 @@ pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
     use rt::task::{Task, GreenTask, SchedTask};
     use rt::local::Local;
 
-    match Local::try_unsafe_borrow::<Task>() {
+    let task_opt: Option<*mut Task> = Local::try_unsafe_borrow();
+    match task_opt {
         Some(t) => {
             match (*t).task_type {
                 GreenTask(_) => {
diff --git a/src/libstd/util.rs b/src/libstd/util.rs
index b46876ad3fe..5085f337d4b 100644
--- a/src/libstd/util.rs
+++ b/src/libstd/util.rs
@@ -54,8 +54,10 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
         let t: *mut T = &mut tmp;
 
         // Perform the swap, `&mut` pointers never alias
-        ptr::copy_nonoverlapping_memory(t, x, 1);
-        ptr::copy_nonoverlapping_memory(x, y, 1);
+        let x_raw: *mut T = x;
+        let y_raw: *mut T = y;
+        ptr::copy_nonoverlapping_memory(t, x_raw, 1);
+        ptr::copy_nonoverlapping_memory(x, y_raw, 1);
         ptr::copy_nonoverlapping_memory(y, t, 1);
 
         // y and t now point to the same thing, but we need to completely forget `tmp`
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 556842e6544..8cd1b09468d 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -1122,14 +1122,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
      * foreign interop.
      */
     #[inline]
-    fn as_imm_buf<U>(&self,
-                     /* NB---this CANNOT be const, see below */
-                     f: &fn(*T, uint) -> U) -> U {
-        // NB---Do not change the type of s to `&const [T]`.  This is
-        // unsound.  The reason is that we are going to create immutable pointers
-        // into `s` and pass them to `f()`, but in fact they are potentially
-        // pointing at *mutable memory*.  Use `as_mut_buf` instead!
-
+    fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U {
         let s = self.repr();
         f(s.data, s.len / sys::nonzero_size_of::<T>())
     }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f09c7427ecc..44015a8b443 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -109,12 +109,21 @@ pub struct Path {
     /// A `::foo` path, is relative to the crate root rather than current
     /// module (like paths in an import).
     global: bool,
-    /// The segments in the path (the things separated by ::)
-    idents: ~[ident],
-    /// "Region parameter", currently only one lifetime is allowed in a path.
-    rp: Option<Lifetime>,
-    /// These are the type parameters, ie, the `a, b` in `foo::bar::<a, b>`
-    types: ~[Ty],
+    /// The segments in the path: the things separated by `::`.
+    segments: ~[PathSegment],
+}
+
+/// A segment of a path: an identifier, an optional lifetime, and a set of
+/// types.
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub struct PathSegment {
+    /// The identifier portion of this path segment.
+    identifier: ident,
+    /// The lifetime parameter for this path segment. Currently only one
+    /// lifetime parameter is allowed.
+    lifetime: Option<Lifetime>,
+    /// The type parameters for this path segment, if present.
+    types: OptVec<Ty>,
 }
 
 pub type CrateNum = int;
@@ -166,11 +175,15 @@ impl Generics {
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub enum MethodProvenance {
+    FromTrait(def_id),
+    FromImpl(def_id),
+}
+
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum def {
     def_fn(def_id, purity),
-    def_static_method(/* method */ def_id,
-                      /* trait */  Option<def_id>,
-                      purity),
+    def_static_method(/* method */ def_id, MethodProvenance, purity),
     def_self(NodeId),
     def_self_ty(/* trait id */ NodeId),
     def_mod(def_id),
@@ -298,7 +311,10 @@ pub enum pat_ {
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
-pub enum mutability { m_mutbl, m_imm, m_const, }
+pub enum mutability {
+    m_mutbl,
+    m_imm,
+}
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum Sigil {
@@ -704,7 +720,7 @@ impl ToStr for float_ty {
 }
 
 // NB Eq method appears below.
-#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct Ty {
     id: NodeId,
     node: ty_,
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index a39da4301ba..2fe42af65ca 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -28,8 +28,8 @@ pub fn path_name_i(idents: &[ident]) -> ~str {
     idents.map(|i| token::interner_get(i.name)).connect("::")
 }
 
-pub fn path_to_ident(p: &Path) -> ident {
-    *p.idents.last()
+pub fn path_to_ident(path: &Path) -> ident {
+    path.segments.last().identifier
 }
 
 pub fn local_def(id: NodeId) -> def_id {
@@ -217,12 +217,18 @@ pub fn default_block(
     }
 }
 
-pub fn ident_to_path(s: span, i: ident) -> Path {
-    ast::Path { span: s,
-                 global: false,
-                 idents: ~[i],
-                 rp: None,
-                 types: ~[] }
+pub fn ident_to_path(s: span, identifier: ident) -> Path {
+    ast::Path {
+        span: s,
+        global: false,
+        segments: ~[
+            ast::PathSegment {
+                identifier: identifier,
+                lifetime: None,
+                types: opt_vec::Empty,
+            }
+        ],
+    }
 }
 
 pub fn ident_to_pat(id: NodeId, s: span, i: ident) -> @pat {
@@ -420,7 +426,7 @@ impl IdVisitor {
 impl Visitor<()> for IdVisitor {
     fn visit_mod(&mut self,
                  module: &_mod,
-                 _span: span,
+                 _: span,
                  node_id: NodeId,
                  env: ()) {
         (self.visit_callback)(node_id);
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 6f9585652bd..7432cf80a41 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -329,20 +329,6 @@ pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: &str) -> @str {
     }
 }
 
-pub fn expr_to_ident(cx: @ExtCtxt,
-                     expr: @ast::expr,
-                     err_msg: &str) -> ast::ident {
-    match expr.node {
-      ast::expr_path(ref p) => {
-        if p.types.len() > 0u || p.idents.len() != 1u {
-            cx.span_fatal(expr.span, err_msg);
-        }
-        return p.idents[0];
-      }
-      _ => cx.span_fatal(expr.span, err_msg)
-    }
-}
-
 pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
                       name: &str) {
     if tts.len() != 0 {
@@ -353,15 +339,15 @@ pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
 pub fn get_single_str_from_tts(cx: @ExtCtxt,
                                sp: span,
                                tts: &[ast::token_tree],
-                               name: &str) -> @str {
+                               name: &str)
+                               -> @str {
     if tts.len() != 1 {
         cx.span_fatal(sp, fmt!("%s takes 1 argument.", name));
     }
 
     match tts[0] {
         ast::tt_tok(_, token::LIT_STR(ident)) => cx.str_of(ident),
-        _ =>
-        cx.span_fatal(sp, fmt!("%s requires a string.", name))
+        _ => cx.span_fatal(sp, fmt!("%s requires a string.", name)),
     }
 }
 
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 9f179672422..21d67493cbf 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -74,6 +74,13 @@ pub trait AstBuilder {
     // statements
     fn stmt_expr(&self, expr: @ast::expr) -> @ast::stmt;
     fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt;
+    fn stmt_let_typed(&self,
+                      sp: span,
+                      mutbl: bool,
+                      ident: ast::ident,
+                      typ: ast::Ty,
+                      ex: @ast::expr)
+                      -> @ast::stmt;
 
     // blocks
     fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::Block;
@@ -233,18 +240,31 @@ impl AstBuilder for @ExtCtxt {
     fn path_global(&self, span: span, strs: ~[ast::ident]) -> ast::Path {
         self.path_all(span, true, strs, None, ~[])
     }
-    fn path_all(&self, sp: span,
+    fn path_all(&self,
+                sp: span,
                 global: bool,
-                idents: ~[ast::ident],
+                mut idents: ~[ast::ident],
                 rp: Option<ast::Lifetime>,
                 types: ~[ast::Ty])
-        -> ast::Path {
+                -> ast::Path {
+        let last_identifier = idents.pop();
+        let mut segments: ~[ast::PathSegment] = idents.move_iter()
+                                                      .map(|ident| {
+            ast::PathSegment {
+                identifier: ident,
+                lifetime: None,
+                types: opt_vec::Empty,
+            }
+        }).collect();
+        segments.push(ast::PathSegment {
+            identifier: last_identifier,
+            lifetime: rp,
+            types: opt_vec::from(types),
+        });
         ast::Path {
             span: sp,
             global: global,
-            idents: idents,
-            rp: rp,
-            types: types
+            segments: segments,
         }
     }
 
@@ -387,6 +407,26 @@ impl AstBuilder for @ExtCtxt {
         @respan(sp, ast::stmt_decl(@decl, self.next_id()))
     }
 
+    fn stmt_let_typed(&self,
+                      sp: span,
+                      mutbl: bool,
+                      ident: ast::ident,
+                      typ: ast::Ty,
+                      ex: @ast::expr)
+                      -> @ast::stmt {
+        let pat = self.pat_ident(sp, ident);
+        let local = @ast::Local {
+            is_mutbl: mutbl,
+            ty: typ,
+            pat: pat,
+            init: Some(ex),
+            id: self.next_id(),
+            span: sp,
+        };
+        let decl = respan(sp, ast::decl_local(local));
+        @respan(sp, ast::stmt_decl(@decl, self.next_id()))
+    }
+
     fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::Block {
         self.block_all(span, ~[], stmts, expr)
     }
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index edb5c634d56..477f3fde99c 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -12,6 +12,7 @@ use ast;
 use codemap::span;
 use ext::base::*;
 use ext::base;
+use opt_vec;
 use parse::token;
 use parse::token::{str_to_ident};
 
@@ -39,9 +40,13 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
             ast::Path {
                  span: sp,
                  global: false,
-                 idents: ~[res],
-                 rp: None,
-                 types: ~[],
+                 segments: ~[
+                    ast::PathSegment {
+                        identifier: res,
+                        lifetime: None,
+                        types: opt_vec::Empty,
+                    }
+                ]
             }
         ),
         span: sp,
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index e55a96f77ff..b8cf3de635f 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -76,24 +76,33 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
 
             let variant_count = cx.expr_uint(span, variants.len());
 
-            // need to specify the uint-ness of the random number
-            let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
-            let r_ty = cx.ty_ident(span, cx.ident_of("R"));
             let rand_name = cx.path_all(span,
                                         true,
                                         rand_ident.clone(),
                                         None,
-                                        ~[ uint_ty, r_ty ]);
+                                        ~[]);
             let rand_name = cx.expr_path(rand_name);
 
-            // ::std::rand::Rand::rand::<uint>(rng)
+            // ::std::rand::Rand::rand(rng)
             let rv_call = cx.expr_call(span,
                                        rand_name,
                                        ~[ rng[0].duplicate(cx) ]);
 
+            // need to specify the uint-ness of the random number
+            let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
+            let value_ident = cx.ident_of("__value");
+            let let_statement = cx.stmt_let_typed(span,
+                                                  false,
+                                                  value_ident,
+                                                  uint_ty,
+                                                  rv_call);
+
             // rand() % variants.len()
-            let rand_variant = cx.expr_binary(span, ast::rem,
-                                              rv_call, variant_count);
+            let value_ref = cx.expr_ident(span, value_ident);
+            let rand_variant = cx.expr_binary(span,
+                                              ast::rem,
+                                              value_ref,
+                                              variant_count);
 
             let mut arms = do variants.iter().enumerate().map |(i, id_sum)| {
                 let i_expr = cx.expr_uint(span, i);
@@ -111,7 +120,10 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
             // _ => {} at the end. Should never occur
             arms.push(cx.arm_unreachable(span));
 
-            cx.expr_match(span, rand_variant, arms)
+            let match_expr = cx.expr_match(span, rand_variant, arms);
+
+            let block = cx.block(span, ~[ let_statement ], Some(match_expr));
+            cx.expr_block(block)
         }
         _ => cx.bug("Non-static method in `deriving(Rand)`")
     };
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 7b493e11ef7..86639c6f121 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -19,6 +19,7 @@ use codemap;
 use codemap::{span, spanned, ExpnInfo, NameAndSpan};
 use ext::base::*;
 use fold::*;
+use opt_vec;
 use parse;
 use parse::{parse_item_from_source_str};
 use parse::token;
@@ -42,13 +43,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
             match (*mac).node {
                 // Token-tree macros:
                 mac_invoc_tt(ref pth, ref tts) => {
-                    if (pth.idents.len() > 1u) {
+                    if (pth.segments.len() > 1u) {
                         cx.span_fatal(
                             pth.span,
                             fmt!("expected macro name without module \
                                   separators"));
                     }
-                    let extname = &pth.idents[0];
+                    let extname = &pth.segments[0].identifier;
                     let extnamestr = ident_to_str(extname);
                     // leaving explicit deref here to highlight unbox op:
                     match (*extsbox).find(&extname.name) {
@@ -143,9 +144,13 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                 ast::Path {
                     span: span,
                     global: false,
-                    idents: ~[ident],
-                    rp: None,
-                    types: ~[]
+                    segments: ~[
+                        ast::PathSegment {
+                            identifier: ident,
+                            lifetime: None,
+                            types: opt_vec::Empty,
+                        }
+                    ],
                 }
             }
 
@@ -368,7 +373,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
         _ => cx.span_bug(it.span, "invalid item macro invocation")
     };
 
-    let extname = &pth.idents[0];
+    let extname = &pth.segments[0].identifier;
     let extnamestr = ident_to_str(extname);
     let expanded = match (*extsbox).find(&extname.name) {
         None => cx.span_fatal(pth.span,
@@ -459,13 +464,13 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
         }
         _ => return orig(s, sp, fld)
     };
-    if (pth.idents.len() > 1u) {
+    if (pth.segments.len() > 1u) {
         cx.span_fatal(
             pth.span,
             fmt!("expected macro name without module \
                   separators"));
     }
-    let extname = &pth.idents[0];
+    let extname = &pth.segments[0].identifier;
     let extnamestr = ident_to_str(extname);
     let (fully_expanded, sp) = match (*extsbox).find(&extname.name) {
         None =>
@@ -534,10 +539,14 @@ impl Visitor<()> for NewNameFinderContext {
                     // a path of length one:
                     &ast::Path {
                         global: false,
-                        idents: [id],
                         span: _,
-                        rp: _,
-                        types: _
+                        segments: [
+                            ast::PathSegment {
+                                identifier: id,
+                                lifetime: _,
+                                types: _
+                            }
+                        ]
                     } => self.ident_accumulator.push(id),
                     // I believe these must be enums...
                     _ => ()
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index c208a7f7e3e..327ee331c38 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -16,8 +16,8 @@ use codemap::{BytePos, mk_sp};
 use codemap;
 use parse::lexer::*; //resolve bug?
 use parse::ParseSess;
-use parse::parser::Parser;
 use parse::attr::parser_attr;
+use parse::parser::{LifetimeAndTypesWithoutColons, Parser};
 use parse::token::{Token, EOF, to_str, nonterminal, get_ident_interner, ident_to_str};
 use parse::token;
 
@@ -430,7 +430,9 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal {
         _ => p.fatal(~"expected ident, found "
                      + token::to_str(get_ident_interner(), p.token))
       },
-      "path" => token::nt_path(~p.parse_path_with_tps(false)),
+      "path" => {
+        token::nt_path(~p.parse_path(LifetimeAndTypesWithoutColons).path)
+      }
       "attr" => token::nt_attr(@p.parse_attribute(false)),
       "tt" => {
         *p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 65694f013f7..458737e2fbf 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -765,9 +765,11 @@ fn noop_fold_path(p: &Path, fld: @ast_fold) -> Path {
     ast::Path {
         span: fld.new_span(p.span),
         global: p.global,
-        idents: p.idents.map(|x| fld.fold_ident(*x)),
-        rp: p.rp,
-        types: p.types.map(|x| fld.fold_ty(x)),
+        segments: p.segments.map(|segment| ast::PathSegment {
+            identifier: fld.fold_ident(segment.identifier),
+            lifetime: segment.lifetime,
+            types: segment.types.map(|typ| fld.fold_ty(typ)),
+        })
     }
 }
 
diff --git a/src/libsyntax/oldvisit.rs b/src/libsyntax/oldvisit.rs
index 295003c6ef5..56576ee3599 100644
--- a/src/libsyntax/oldvisit.rs
+++ b/src/libsyntax/oldvisit.rs
@@ -284,7 +284,11 @@ pub fn visit_ty<E:Clone>(t: &Ty, (e, v): (E, vt<E>)) {
 }
 
 pub fn visit_path<E:Clone>(p: &Path, (e, v): (E, vt<E>)) {
-    for tp in p.types.iter() { (v.visit_ty)(tp, (e.clone(), v)); }
+    for segment in p.segments.iter() {
+        for typ in segment.types.iter() {
+            (v.visit_ty)(typ, (e.clone(), v))
+        }
+    }
 }
 
 pub fn visit_pat<E:Clone>(p: &pat, (e, v): (E, vt<E>)) {
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 23c6a8b9720..81113f24329 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -361,27 +361,47 @@ mod test {
         span{lo:BytePos(a),hi:BytePos(b),expn_info:None}
     }
 
-    #[test] fn path_exprs_1 () {
+    #[test] fn path_exprs_1() {
         assert_eq!(string_to_expr(@"a"),
-                   @ast::expr{id:1,
-                              node:ast::expr_path(ast::Path {span:sp(0,1),
-                                                              global:false,
-                                                              idents:~[str_to_ident("a")],
-                                                              rp:None,
-                                                              types:~[]}),
-                              span:sp(0,1)})
+                   @ast::expr{
+                    id: 1,
+                    node: ast::expr_path(ast::Path {
+                        span: sp(0, 1),
+                        global: false,
+                        segments: ~[
+                            ast::PathSegment {
+                                identifier: str_to_ident("a"),
+                                lifetime: None,
+                                types: opt_vec::Empty,
+                            }
+                        ],
+                    }),
+                    span: sp(0, 1)
+                   })
     }
 
     #[test] fn path_exprs_2 () {
         assert_eq!(string_to_expr(@"::a::b"),
-                   @ast::expr{id:1,
-                               node:ast::expr_path(
-                                    ast::Path {span:sp(0,6),
-                                               global:true,
-                                               idents:strs_to_idents(~["a","b"]),
-                                               rp:None,
-                                               types:~[]}),
-                              span:sp(0,6)})
+                   @ast::expr {
+                    id:1,
+                    node: ast::expr_path(ast::Path {
+                            span: sp(0, 6),
+                            global: true,
+                            segments: ~[
+                                ast::PathSegment {
+                                    identifier: str_to_ident("a"),
+                                    lifetime: None,
+                                    types: opt_vec::Empty,
+                                },
+                                ast::PathSegment {
+                                    identifier: str_to_ident("b"),
+                                    lifetime: None,
+                                    types: opt_vec::Empty,
+                                }
+                            ]
+                        }),
+                    span: sp(0, 6)
+                   })
     }
 
     #[should_fail]
@@ -420,32 +440,43 @@ mod test {
 
     #[test] fn ret_expr() {
         assert_eq!(string_to_expr(@"return d"),
-                   @ast::expr{id:2,
-                              node:ast::expr_ret(
-                                  Some(@ast::expr{id:1,
-                                                  node:ast::expr_path(
-                                                       ast::Path{span:sp(7,8),
-                                                                 global:false,
-                                                                 idents:~[str_to_ident("d")],
-                                                                 rp:None,
-                                                                 types:~[]
-                                                                }),
-                                                  span:sp(7,8)})),
-                              span:sp(0,8)})
+                   @ast::expr{
+                    id:2,
+                    node:ast::expr_ret(Some(@ast::expr{
+                        id:1,
+                        node:ast::expr_path(ast::Path{
+                            span: sp(7, 8),
+                            global: false,
+                            segments: ~[
+                                ast::PathSegment {
+                                    identifier: str_to_ident("d"),
+                                    lifetime: None,
+                                    types: opt_vec::Empty,
+                                }
+                            ],
+                        }),
+                        span:sp(7,8)
+                    })),
+                    span:sp(0,8)
+                   })
     }
 
     #[test] fn parse_stmt_1 () {
         assert_eq!(string_to_stmt(@"b;"),
                    @spanned{
-                       node: ast::stmt_expr(@ast::expr{
+                       node: ast::stmt_expr(@ast::expr {
                            id: 1,
-                           node: ast::expr_path(
-                                ast::Path{
-                                   span:sp(0,1),
-                                   global:false,
-                                   idents:~[str_to_ident("b")],
-                                   rp:None,
-                                   types: ~[]}),
+                           node: ast::expr_path(ast::Path {
+                               span:sp(0,1),
+                               global:false,
+                               segments: ~[
+                                ast::PathSegment {
+                                    identifier: str_to_ident("b"),
+                                    lifetime: None,
+                                    types: opt_vec::Empty,
+                                }
+                               ],
+                            }),
                            span: sp(0,1)},
                                             2), // fixme
                        span: sp(0,1)})
@@ -460,49 +491,24 @@ mod test {
         let parser = string_to_parser(@"b");
         assert_eq!(parser.parse_pat(),
                    @ast::pat{id:1, // fixme
-                             node: ast::pat_ident(ast::bind_infer,
-                                                   ast::Path{
-                                                      span:sp(0,1),
-                                                      global:false,
-                                                      idents:~[str_to_ident("b")],
-                                                      rp: None,
-                                                      types: ~[]},
-                                                  None // no idea
-                                                 ),
+                             node: ast::pat_ident(
+                                ast::bind_infer,
+                                ast::Path {
+                                    span:sp(0,1),
+                                    global:false,
+                                    segments: ~[
+                                        ast::PathSegment {
+                                            identifier: str_to_ident("b"),
+                                            lifetime: None,
+                                            types: opt_vec::Empty,
+                                        }
+                                    ],
+                                },
+                                None /* no idea */),
                              span: sp(0,1)});
         parser_done(parser);
     }
 
-    #[test] fn parse_arg () {
-        let parser = string_to_parser(@"b : int");
-        assert_eq!(parser.parse_arg_general(true),
-                   ast::arg{
-                       is_mutbl: false,
-                       ty: ast::Ty{id:3, // fixme
-                                    node: ast::ty_path(ast::Path{
-                                        span:sp(4,4), // this is bizarre...
-                                        // check this in the original parser?
-                                        global:false,
-                                        idents:~[str_to_ident("int")],
-                                        rp: None,
-                                        types: ~[]},
-                                                       None, 2),
-                                    span:sp(4,7)},
-                       pat: @ast::pat{id:1,
-                                      node: ast::pat_ident(ast::bind_infer,
-                                                            ast::Path{
-                                                               span:sp(0,1),
-                                                               global:false,
-                                                               idents:~[str_to_ident("b")],
-                                                               rp: None,
-                                                               types: ~[]},
-                                                           None // no idea
-                                                          ),
-                                      span: sp(0,1)},
-                       id: 4 // fixme
-                   })
-    }
-
     // check the contents of the tt manually:
     #[test] fn parse_fundecl () {
         // this test depends on the intern order of "fn" and "int", and on the
@@ -519,23 +525,37 @@ mod test {
                                                 node: ast::ty_path(ast::Path{
                                         span:sp(10,13),
                                         global:false,
-                                        idents:~[str_to_ident("int")],
-                                        rp: None,
-                                        types: ~[]},
-                                                       None, 2),
-                                                span:sp(10,13)},
-                                    pat: @ast::pat{id:1, // fixme
-                                                   node: ast::pat_ident(
-                                                       ast::bind_infer,
-                                                       ast::Path{
-                                                           span:sp(6,7),
-                                                           global:false,
-                                                           idents:~[str_to_ident("b")],
-                                                           rp: None,
-                                                           types: ~[]},
-                                                       None // no idea
-                                                   ),
-                                                  span: sp(6,7)},
+                                        segments: ~[
+                                            ast::PathSegment {
+                                                identifier:
+                                                    str_to_ident("int"),
+                                                lifetime: None,
+                                                types: opt_vec::Empty,
+                                            }
+                                        ],
+                                        }, None, 2),
+                                        span:sp(10,13)
+                                    },
+                                    pat: @ast::pat {
+                                        id:1, // fixme
+                                        node: ast::pat_ident(
+                                            ast::bind_infer,
+                                            ast::Path {
+                                                span:sp(6,7),
+                                                global:false,
+                                                segments: ~[
+                                                    ast::PathSegment {
+                                                        identifier:
+                                                            str_to_ident("b"),
+                                                        lifetime: None,
+                                                        types: opt_vec::Empty,
+                                                    }
+                                                ],
+                                            },
+                                            None // no idea
+                                        ),
+                                        span: sp(6,7)
+                                    },
                                     id: 4 // fixme
                                 }],
                                 output: ast::Ty{id:5, // fixme
@@ -558,9 +578,18 @@ mod test {
                                                       ast::Path{
                                                         span:sp(17,18),
                                                         global:false,
-                                                        idents:~[str_to_ident("b")],
-                                                        rp:None,
-                                                        types: ~[]}),
+                                                        segments: ~[
+                                                            ast::PathSegment {
+                                                                identifier:
+                                                                str_to_ident(
+                                                                    "b"),
+                                                                lifetime:
+                                                                    None,
+                                                                types:
+                                                                opt_vec::Empty
+                                                            }
+                                                        ],
+                                                      }),
                                                 span: sp(17,18)},
                                                                  7), // fixme
                                             span: sp(17,18)}],
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 989a796cbc9..ab1bde3a3b9 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -53,7 +53,6 @@ pub enum ObsoleteSyntax {
     ObsoleteMode,
     ObsoleteImplicitSelf,
     ObsoleteLifetimeNotation,
-    ObsoleteConstManagedPointer,
     ObsoletePurity,
     ObsoleteStaticMethod,
     ObsoleteConstItem,
@@ -65,6 +64,7 @@ pub enum ObsoleteSyntax {
     ObsoleteUnsafeExternFn,
     ObsoletePrivVisibility,
     ObsoleteTraitFuncVisibility,
+    ObsoleteConstPointer,
 }
 
 impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -201,10 +201,6 @@ impl ParserObsoleteMethods for Parser {
                 "instead of `&foo/bar`, write `&'foo bar`; instead of \
                  `bar/&foo`, write `&bar<'foo>"
             ),
-            ObsoleteConstManagedPointer => (
-                "const `@` pointer",
-                "instead of `@const Foo`, write `@Foo`"
-            ),
             ObsoletePurity => (
                 "pure function",
                 "remove `pure`"
@@ -255,6 +251,11 @@ impl ParserObsoleteMethods for Parser {
                 "visibility not necessary",
                 "trait functions inherit the visibility of the trait itself"
             ),
+            ObsoleteConstPointer => (
+                "const pointer",
+                "instead of `&const Foo` or `@const Foo`, write `&Foo` or \
+                 `@Foo`"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 9aa2bf3f063..8ca858b7935 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -38,7 +38,7 @@ use ast::{ident, impure_fn, inherited, item, item_, item_static};
 use ast::{item_enum, item_fn, item_foreign_mod, item_impl};
 use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
 use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
-use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local, m_const};
+use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, Local};
 use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal};
 use ast::{match_seq, match_tok, method, mt, mul, mutability};
 use ast::{named_field, neg, NodeId, noreturn, not, pat, pat_box, pat_enum};
@@ -97,6 +97,37 @@ enum restriction {
 type arg_or_capture_item = Either<arg, ()>;
 type item_info = (ident, item_, Option<~[Attribute]>);
 
+/// How to parse a path. There are four different kinds of paths, all of which
+/// are parsed somewhat differently.
+#[deriving(Eq)]
+pub enum PathParsingMode {
+    /// A path with no type parameters; e.g. `foo::bar::Baz`
+    NoTypesAllowed,
+    /// A path with a lifetime and type parameters, with no double colons
+    /// before the type parameters; e.g. `foo::bar<'self>::Baz<T>`
+    LifetimeAndTypesWithoutColons,
+    /// A path with a lifetime and type parameters with double colons before
+    /// the type parameters; e.g. `foo::bar::<'self>::Baz::<T>`
+    LifetimeAndTypesWithColons,
+    /// A path with a lifetime and type parameters with bounds before the last
+    /// set of type parameters only; e.g. `foo::bar<'self>::Baz:X+Y<T>` This
+    /// form does not use extra double colons.
+    LifetimeAndTypesAndBounds,
+}
+
+/// A pair of a path segment and group of type parameter bounds. (See `ast.rs`
+/// for the definition of a path segment.)
+struct PathSegmentAndBoundSet {
+    segment: ast::PathSegment,
+    bound_set: Option<OptVec<TyParamBound>>,
+}
+
+/// A path paired with optional type bounds.
+struct PathAndBounds {
+    path: ast::Path,
+    bounds: Option<OptVec<TyParamBound>>,
+}
+
 pub enum item_or_view_item {
     // Indicates a failure to parse any kind of item. The attributes are
     // returned.
@@ -1108,7 +1139,10 @@ impl Parser {
         } else if *self.token == token::MOD_SEP
             || is_ident_or_path(self.token) {
             // NAMED TYPE
-            let (path, bounds) = self.parse_type_path();
+            let PathAndBounds {
+                path,
+                bounds
+            } = self.parse_path(LifetimeAndTypesAndBounds);
             ty_path(path, bounds, self.get_id())
         } else {
             self.fatal(fmt!("expected type, found token %?",
@@ -1153,9 +1187,6 @@ impl Parser {
         if mt.mutbl != m_imm && sigil == OwnedSigil {
             self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
         }
-        if mt.mutbl == m_const && sigil == ManagedSigil {
-            self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
-        }
 
         ctor(mt)
     }
@@ -1332,139 +1363,155 @@ impl Parser {
         }
     }
 
-    // parse a path into a vector of idents, whether the path starts
-    // with ::, and a span.
-    pub fn parse_path(&self) -> (~[ast::ident],bool,span) {
+    /// Parses a path and optional type parameter bounds, depending on the
+    /// mode. The `mode` parameter determines whether lifetimes, types, and/or
+    /// bounds are permitted and whether `::` must precede type parameter
+    /// groups.
+    pub fn parse_path(&self, mode: PathParsingMode) -> PathAndBounds {
+        // Check for a whole path...
+        let found = match *self.token {
+            INTERPOLATED(token::nt_path(_)) => Some(self.bump_and_get()),
+            _ => None,
+        };
+        match found {
+            Some(INTERPOLATED(token::nt_path(~path))) => {
+                return PathAndBounds {
+                    path: path,
+                    bounds: None,
+                }
+            }
+            _ => {}
+        }
+
         let lo = self.span.lo;
         let is_global = self.eat(&token::MOD_SEP);
-        let (ids,span{lo:_,hi,expn_info}) = self.parse_path_non_global();
-        (ids,is_global,span{lo:lo,hi:hi,expn_info:expn_info})
-    }
 
-    // parse a path beginning with an identifier into a vector of idents and a span
-    pub fn parse_path_non_global(&self) -> (~[ast::ident],span) {
-        let lo = self.span.lo;
-        let mut ids = ~[];
-        // must be at least one to begin:
-        ids.push(self.parse_ident());
+        // Parse any number of segments and bound sets. A segment is an
+        // identifier followed by an optional lifetime and a set of types.
+        // A bound set is a set of type parameter bounds.
+        let mut segments = ~[];
         loop {
+            // First, parse an identifier.
             match *self.token {
-                token::MOD_SEP => {
-                    let is_ident = do self.look_ahead(1) |t| {
-                        match *t {
-                            token::IDENT(*) => true,
-                            _ => false,
-                        }
-                    };
-                    if is_ident {
-                        self.bump();
-                        ids.push(self.parse_ident());
-                    } else {
-                        break
-                    }
-                }
-                _ => break
+                token::IDENT(*) => {}
+                _ => break,
             }
-        }
-        (ids, mk_sp(lo, self.last_span.hi))
-    }
+            let identifier = self.parse_ident();
 
-    // parse a path that doesn't have type parameters attached
-    pub fn parse_path_without_tps(&self) -> ast::Path {
-        maybe_whole!(deref self, nt_path);
-        let (ids,is_global,sp) = self.parse_path();
-        ast::Path { span: sp,
-                     global: is_global,
-                     idents: ids,
-                     rp: None,
-                     types: ~[] }
-    }
+            // Next, parse a colon and bounded type parameters, if applicable.
+            let bound_set = if mode == LifetimeAndTypesAndBounds {
+                self.parse_optional_ty_param_bounds()
+            } else {
+                None
+            };
 
-    pub fn parse_bounded_path_with_tps(&self, colons: bool,
-                                        before_tps: Option<&fn()>) -> ast::Path {
-        debug!("parse_path_with_tps(colons=%b)", colons);
+            // Parse the '::' before type parameters if it's required. If
+            // it is required and wasn't present, then we're done.
+            if mode == LifetimeAndTypesWithColons &&
+                    !self.eat(&token::MOD_SEP) {
+                segments.push(PathSegmentAndBoundSet {
+                    segment: ast::PathSegment {
+                        identifier: identifier,
+                        lifetime: None,
+                        types: opt_vec::Empty,
+                    },
+                    bound_set: bound_set
+                });
+                break
+            }
 
-        maybe_whole!(deref self, nt_path);
-        let lo = self.span.lo;
-        let path = self.parse_path_without_tps();
-        if colons && !self.eat(&token::MOD_SEP) {
-            return path;
-        }
-
-        // If the path might have bounds on it, they should be parsed before
-        // the parameters, e.g. module::TraitName:B1+B2<T>
-        before_tps.map_move(|callback| callback());
-
-        // Parse the (obsolete) trailing region parameter, if any, which will
-        // be written "foo/&x"
-        let rp_slash = {
-            if *self.token == token::BINOP(token::SLASH)
-                && self.look_ahead(1, |t| *t == token::BINOP(token::AND))
-            {
-                self.bump(); self.bump();
-                self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
-                match *self.token {
-                    token::IDENT(sid, _) => {
-                        let span = self.span;
-                        self.bump();
-                        Some(ast::Lifetime {
-                            id: self.get_id(),
-                            span: *span,
-                            ident: sid
-                        })
+            // Parse the `<` before the lifetime and types, if applicable.
+            let (any_lifetime_or_types, optional_lifetime, types) =
+                    if mode != NoTypesAllowed && self.eat(&token::LT) {
+                // Parse an optional lifetime.
+                let optional_lifetime = match *self.token {
+                    token::LIFETIME(*) => Some(self.parse_lifetime()),
+                    _ => None,
+                };
+
+                // Parse type parameters.
+                let mut types = opt_vec::Empty;
+                let mut need_comma = optional_lifetime.is_some();
+                loop {
+                    // We're done if we see a `>`.
+                    match *self.token {
+                        token::GT | token::BINOP(token::SHR) => {
+                            self.expect_gt();
+                            break
+                        }
+                        _ => {} // Go on.
                     }
-                    _ => {
-                        self.fatal(fmt!("Expected a lifetime name"));
+
+                    if need_comma {
+                        self.expect(&token::COMMA)
+                    } else {
+                        need_comma = true
                     }
+
+                    types.push(self.parse_ty(false))
                 }
+
+                (true, optional_lifetime, types)
             } else {
-                None
-            }
-        };
+                (false, None, opt_vec::Empty)
+            };
 
-        // Parse any lifetime or type parameters which may appear:
-        let (lifetimes, tps) = self.parse_generic_values();
-        let hi = self.span.lo;
+            // Assemble and push the result.
+            segments.push(PathSegmentAndBoundSet {
+                segment: ast::PathSegment {
+                    identifier: identifier,
+                    lifetime: optional_lifetime,
+                    types: types,
+                },
+                bound_set: bound_set
+            });
 
-        let rp = match (&rp_slash, &lifetimes) {
-            (&Some(_), _) => rp_slash,
-            (&None, v) => {
-                if v.len() == 0 {
-                    None
-                } else if v.len() == 1 {
-                    Some(*v.get(0))
-                } else {
-                    self.fatal(fmt!("Expected at most one \
-                                     lifetime name (for now)"));
+            // We're done if we don't see a '::', unless the mode required
+            // a double colon to get here in the first place.
+            if !(mode == LifetimeAndTypesWithColons &&
+                    !any_lifetime_or_types) {
+                if !self.eat(&token::MOD_SEP) {
+                    break
                 }
             }
-        };
-
-        ast::Path {
-            span: mk_sp(lo, hi),
-            rp: rp,
-            types: tps,
-            .. path.clone()
         }
-    }
 
-    // parse a path optionally with type parameters. If 'colons'
-    // is true, then type parameters must be preceded by colons,
-    // as in a::t::<t1,t2>
-    pub fn parse_path_with_tps(&self, colons: bool) -> ast::Path {
-        self.parse_bounded_path_with_tps(colons, None)
-    }
+        // Assemble the span.
+        let span = mk_sp(lo, self.last_span.hi);
 
-    // Like the above, but can also parse kind bounds in the case of a
-    // path to be used as a type that might be a trait.
-    pub fn parse_type_path(&self) -> (ast::Path, Option<OptVec<TyParamBound>>) {
+        // Assemble the path segments.
+        let mut path_segments = ~[];
         let mut bounds = None;
-        let path = self.parse_bounded_path_with_tps(false, Some(|| {
-            // Note: this closure might not even get called in the case of a
-            // macro-generated path. But that's the macro parser's job.
-            bounds = self.parse_optional_ty_param_bounds();
-        }));
-        (path, bounds)
+        let last_segment_index = segments.len() - 1;
+        for (i, segment_and_bounds) in segments.move_iter().enumerate() {
+            let PathSegmentAndBoundSet {
+                segment: segment,
+                bound_set: bound_set
+            } = segment_and_bounds;
+            path_segments.push(segment);
+
+            if bound_set.is_some() {
+                if i != last_segment_index {
+                    self.span_err(span,
+                                  "type parameter bounds are allowed only \
+                                   before the last segment in a path")
+                }
+
+                bounds = bound_set
+            }
+        }
+
+        // Assemble the result.
+        let path_and_bounds = PathAndBounds {
+            path: ast::Path {
+                span: span,
+                global: is_global,
+                segments: path_segments,
+            },
+            bounds: bounds,
+        };
+
+        path_and_bounds
     }
 
     /// parses 0 or 1 lifetime
@@ -1568,7 +1615,8 @@ impl Parser {
         if self.eat_keyword(keywords::Mut) {
             m_mutbl
         } else if self.eat_keyword(keywords::Const) {
-            m_const
+            self.obsolete(*self.last_span, ObsoleteConstPointer);
+            m_imm
         } else {
             m_imm
         }
@@ -1727,7 +1775,7 @@ impl Parser {
         } else if *self.token == token::LBRACKET {
             self.bump();
             let mutbl = self.parse_mutability();
-            if mutbl == m_mutbl || mutbl == m_const {
+            if mutbl == m_mutbl {
                 self.obsolete(*self.last_span, ObsoleteMutVector);
             }
 
@@ -1791,7 +1839,7 @@ impl Parser {
         } else if *self.token == token::MOD_SEP ||
                 is_ident(&*self.token) && !self.is_keyword(keywords::True) &&
                 !self.is_keyword(keywords::False) {
-            let pth = self.parse_path_with_tps(true);
+            let pth = self.parse_path(LifetimeAndTypesWithColons).path;
 
             // `!`, as an operator, is prefix, so we know this isn't that
             if *self.token == token::NOT {
@@ -2182,10 +2230,6 @@ impl Parser {
           token::AT => {
             self.bump();
             let m = self.parse_mutability();
-            if m == m_const {
-                self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
-            }
-
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
             // HACK: turn @[...] into a @-evec
@@ -2886,7 +2930,8 @@ impl Parser {
             let val = self.parse_literal_maybe_minus();
             if self.eat(&token::DOTDOT) {
                 let end = if is_ident_or_path(tok) {
-                    let path = self.parse_path_with_tps(true);
+                    let path = self.parse_path(LifetimeAndTypesWithColons)
+                                   .path;
                     let hi = self.span.hi;
                     self.mk_expr(lo, hi, expr_path(path))
                 } else {
@@ -2915,7 +2960,7 @@ impl Parser {
                 let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
                 pat = pat_range(start, end);
             } else if is_plain_ident(&*self.token) && !can_be_enum_or_struct {
-                let name = self.parse_path_without_tps();
+                let name = self.parse_path(NoTypesAllowed).path;
                 let sub;
                 if self.eat(&token::AT) {
                     // parse foo @ pat
@@ -2927,7 +2972,8 @@ impl Parser {
                 pat = pat_ident(bind_infer, name, sub);
             } else {
                 // parse an enum pat
-                let enum_path = self.parse_path_with_tps(true);
+                let enum_path = self.parse_path(LifetimeAndTypesWithColons)
+                                    .path;
                 match *self.token {
                     token::LBRACE => {
                         self.bump();
@@ -2963,7 +3009,7 @@ impl Parser {
                             }
                           },
                           _ => {
-                              if enum_path.idents.len()==1u {
+                              if enum_path.segments.len() == 1 {
                                   // it could still be either an enum
                                   // or an identifier pattern, resolve
                                   // will sort it out:
@@ -2998,7 +3044,7 @@ impl Parser {
                             "expected identifier, found path");
         }
         // why a path here, and not just an identifier?
-        let name = self.parse_path_without_tps();
+        let name = self.parse_path(NoTypesAllowed).path;
         let sub = if self.eat(&token::AT) {
             Some(self.parse_pat())
         } else {
@@ -3115,7 +3161,7 @@ impl Parser {
 
             // Potential trouble: if we allow macros with paths instead of
             // idents, we'd need to look ahead past the whole path here...
-            let pth = self.parse_path_without_tps();
+            let pth = self.parse_path(NoTypesAllowed).path;
             self.bump();
 
             let id = if *self.token == token::LPAREN {
@@ -3791,7 +3837,7 @@ impl Parser {
     // parse a::B<~str,int>
     fn parse_trait_ref(&self) -> trait_ref {
         ast::trait_ref {
-            path: self.parse_path_with_tps(false),
+            path: self.parse_path(LifetimeAndTypesWithoutColons).path,
             ref_id: self.get_id(),
         }
     }
@@ -4707,7 +4753,7 @@ impl Parser {
             }
 
             // item macro.
-            let pth = self.parse_path_without_tps();
+            let pth = self.parse_path(NoTypesAllowed).path;
             self.expect(&token::NOT);
 
             // a 'special' identifier (like what `macro_rules!` uses)
@@ -4791,11 +4837,17 @@ impl Parser {
                 let id = self.parse_ident();
                 path.push(id);
             }
-            let path = ast::Path { span: mk_sp(lo, self.span.hi),
-                                    global: false,
-                                    idents: path,
-                                    rp: None,
-                                    types: ~[] };
+            let path = ast::Path {
+                span: mk_sp(lo, self.span.hi),
+                global: false,
+                segments: path.move_iter().map(|identifier| {
+                    ast::PathSegment {
+                        identifier: identifier,
+                        lifetime: None,
+                        types: opt_vec::Empty,
+                    }
+                }).collect()
+            };
             return @spanned(lo, self.span.hi,
                             view_path_simple(first_ident,
                                              path,
@@ -4821,11 +4873,17 @@ impl Parser {
                         seq_sep_trailing_allowed(token::COMMA),
                         |p| p.parse_path_list_ident()
                     );
-                    let path = ast::Path { span: mk_sp(lo, self.span.hi),
-                                            global: false,
-                                            idents: path,
-                                            rp: None,
-                                            types: ~[] };
+                    let path = ast::Path {
+                        span: mk_sp(lo, self.span.hi),
+                        global: false,
+                        segments: path.move_iter().map(|identifier| {
+                            ast::PathSegment {
+                                identifier: identifier,
+                                lifetime: None,
+                                types: opt_vec::Empty,
+                            }
+                        }).collect()
+                    };
                     return @spanned(lo, self.span.hi,
                                  view_path_list(path, idents, self.get_id()));
                   }
@@ -4833,11 +4891,17 @@ impl Parser {
                   // foo::bar::*
                   token::BINOP(token::STAR) => {
                     self.bump();
-                    let path = ast::Path { span: mk_sp(lo, self.span.hi),
-                                            global: false,
-                                            idents: path,
-                                            rp: None,
-                                            types: ~[] };
+                    let path = ast::Path {
+                        span: mk_sp(lo, self.span.hi),
+                        global: false,
+                        segments: path.move_iter().map(|identifier| {
+                            ast::PathSegment {
+                                identifier: identifier,
+                                lifetime: None,
+                                types: opt_vec::Empty,
+                            }
+                        }).collect()
+                    };
                     return @spanned(lo, self.span.hi,
                                     view_path_glob(path, self.get_id()));
                   }
@@ -4849,11 +4913,17 @@ impl Parser {
           _ => ()
         }
         let last = path[path.len() - 1u];
-        let path = ast::Path { span: mk_sp(lo, self.span.hi),
-                                global: false,
-                                idents: path,
-                                rp: None,
-                                types: ~[] };
+        let path = ast::Path {
+            span: mk_sp(lo, self.span.hi),
+            global: false,
+            segments: path.move_iter().map(|identifier| {
+                ast::PathSegment {
+                    identifier: identifier,
+                    lifetime: None,
+                    types: opt_vec::Empty,
+                }
+            }).collect()
+        };
         return @spanned(lo,
                         self.last_span.hi,
                         view_path_simple(last, path, self.get_id()));
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 3bad1ed9384..d449ba4eb5f 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -386,7 +386,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
         word(s.s, "[");
         match mt.mutbl {
           ast::m_mutbl => word_space(s, "mut"),
-          ast::m_const => word_space(s, "const"),
           ast::m_imm => ()
         }
         print_type(s, mt.ty);
@@ -429,7 +428,6 @@ pub fn print_type(s: @ps, ty: &ast::Ty) {
         word(s.s, "[");
         match mt.mutbl {
             ast::m_mutbl => word_space(s, "mut"),
-            ast::m_const => word_space(s, "const"),
             ast::m_imm => ()
         }
         print_type(s, mt.ty);
@@ -1503,34 +1501,52 @@ pub fn print_for_decl(s: @ps, loc: &ast::Local, coll: &ast::expr) {
     print_expr(s, coll);
 }
 
-fn print_path_(s: @ps, path: &ast::Path, colons_before_params: bool,
+fn print_path_(s: @ps,
+               path: &ast::Path,
+               colons_before_params: bool,
                opt_bounds: &Option<OptVec<ast::TyParamBound>>) {
     maybe_print_comment(s, path.span.lo);
-    if path.global { word(s.s, "::"); }
-    let mut first = true;
-    for id in path.idents.iter() {
-        if first { first = false; } else { word(s.s, "::"); }
-        print_ident(s, *id);
+    if path.global {
+        word(s.s, "::");
     }
-    do opt_bounds.map |bounds| {
-        print_bounds(s, bounds, true);
-    };
-    if path.rp.is_some() || !path.types.is_empty() {
-        if colons_before_params { word(s.s, "::"); }
 
-        if path.rp.is_some() || !path.types.is_empty() {
+    let mut first = true;
+    for (i, segment) in path.segments.iter().enumerate() {
+        if first {
+            first = false
+        } else {
+            word(s.s, "::")
+        }
+
+        print_ident(s, segment.identifier);
+
+        if segment.lifetime.is_some() || !segment.types.is_empty() {
+            // If this is the last segment, print the bounds.
+            if i == path.segments.len() - 1 {
+                match *opt_bounds {
+                    None => {}
+                    Some(ref bounds) => print_bounds(s, bounds, true),
+                }
+            }
+
+            if colons_before_params {
+                word(s.s, "::")
+            }
             word(s.s, "<");
 
-            for r in path.rp.iter() {
-                print_lifetime(s, r);
-                if !path.types.is_empty() {
-                    word_space(s, ",");
+            for lifetime in segment.lifetime.iter() {
+                print_lifetime(s, lifetime);
+                if !segment.types.is_empty() {
+                    word_space(s, ",")
                 }
             }
 
-            commasep(s, inconsistent, path.types, print_type);
+            commasep(s,
+                     inconsistent,
+                     segment.types.map_to_vec(|t| (*t).clone()),
+                     print_type);
 
-            word(s.s, ">");
+            word(s.s, ">")
         }
     }
 }
@@ -1821,7 +1837,7 @@ pub fn print_meta_item(s: @ps, item: &ast::MetaItem) {
 pub fn print_view_path(s: @ps, vp: &ast::view_path) {
     match vp.node {
       ast::view_path_simple(ident, ref path, _) => {
-        if path.idents[path.idents.len()-1u] != ident {
+        if path.segments.last().identifier != ident {
             print_ident(s, ident);
             space(s.s);
             word_space(s, "=");
@@ -1882,7 +1898,6 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) {
 pub fn print_mutability(s: @ps, mutbl: ast::mutability) {
     match mutbl {
       ast::m_mutbl => word_nbsp(s, "mut"),
-      ast::m_const => word_nbsp(s, "const"),
       ast::m_imm => {/* nothing */ }
     }
 }
@@ -1902,8 +1917,9 @@ pub fn print_arg(s: @ps, input: &ast::arg) {
       _ => {
         match input.pat.node {
             ast::pat_ident(_, ref path, _) if
-                path.idents.len() == 1 &&
-                path.idents[0] == parse::token::special_idents::invalid => {
+                path.segments.len() == 1 &&
+                path.segments[0].identifier ==
+                    parse::token::special_idents::invalid => {
                 // Do nothing.
             }
             _ => {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 8178e7f3760..e5b7823ae44 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -319,8 +319,10 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
 }
 
 pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
-    for typ in path.types.iter() {
-        visitor.visit_ty(typ, env.clone())
+    for segment in path.segments.iter() {
+        for typ in segment.types.iter() {
+            visitor.visit_ty(typ, env.clone())
+        }
     }
 }
 
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index 6475012e009..2571d601459 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -121,54 +121,54 @@ fn main() {
     io::println("\nTreeMap:");
 
     {
-        let mut map = TreeMap::new::<uint, uint>();
+        let mut map: TreeMap<uint,uint> = TreeMap::new();
         ascending(&mut map, n_keys);
     }
 
     {
-        let mut map = TreeMap::new::<uint, uint>();
+        let mut map: TreeMap<uint,uint> = TreeMap::new();
         descending(&mut map, n_keys);
     }
 
     {
         io::println(" Random integers:");
-        let mut map = TreeMap::new::<uint, uint>();
+        let mut map: TreeMap<uint,uint> = TreeMap::new();
         vector(&mut map, n_keys, rand);
     }
 
     io::println("\nHashMap:");
 
     {
-        let mut map = HashMap::new::<uint, uint>();
+        let mut map: HashMap<uint,uint> = HashMap::new();
         ascending(&mut map, n_keys);
     }
 
     {
-        let mut map = HashMap::new::<uint, uint>();
+        let mut map: HashMap<uint,uint> = HashMap::new();
         descending(&mut map, n_keys);
     }
 
     {
         io::println(" Random integers:");
-        let mut map = HashMap::new::<uint, uint>();
+        let mut map: HashMap<uint,uint> = HashMap::new();
         vector(&mut map, n_keys, rand);
     }
 
     io::println("\nTrieMap:");
 
     {
-        let mut map = TrieMap::new::<uint>();
+        let mut map: TrieMap<uint> = TrieMap::new();
         ascending(&mut map, n_keys);
     }
 
     {
-        let mut map = TrieMap::new::<uint>();
+        let mut map: TrieMap<uint> = TrieMap::new();
         descending(&mut map, n_keys);
     }
 
     {
         io::println(" Random integers:");
-        let mut map = TrieMap::new::<uint>();
+        let mut map: TrieMap<uint> = TrieMap::new();
         vector(&mut map, n_keys, rand);
     }
 }
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 22622c1cac3..fe77196e2b1 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -169,16 +169,28 @@ fn main() {
     {
         let mut rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(&mut rng, num_keys, max, || HashSet::new::<uint>());
-        results.bench_str(&mut rng, num_keys, || HashSet::new::<~str>());
+        results.bench_int(&mut rng, num_keys, max, || {
+            let s: HashSet<uint> = HashSet::new();
+            s
+        });
+        results.bench_str(&mut rng, num_keys, || {
+            let s: HashSet<~str> = HashSet::new();
+            s
+        });
         write_results("std::hashmap::HashSet", &results);
     }
 
     {
         let mut rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(&mut rng, num_keys, max, || TreeSet::new::<uint>());
-        results.bench_str(&mut rng, num_keys, || TreeSet::new::<~str>());
+        results.bench_int(&mut rng, num_keys, max, || {
+            let s: TreeSet<uint> = TreeSet::new();
+            s
+        });
+        results.bench_str(&mut rng, num_keys, || {
+            let s: TreeSet<~str> = TreeSet::new();
+            s
+        });
         write_results("extra::treemap::TreeSet", &results);
     }
 
diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs
new file mode 100644
index 00000000000..e4833345d31
--- /dev/null
+++ b/src/test/compile-fail/bad-mid-path-type-params.rs
@@ -0,0 +1,37 @@
+#[no_std];
+
+struct S<T> {
+    contents: T,
+}
+
+impl<T> S<T> {
+    fn new<U>(x: T, _: U) -> S<T> {
+        S {
+            contents: x,
+        }
+    }
+}
+
+trait Trait<T> {
+    fn new<U>(x: T, y: U) -> Self;
+}
+
+struct S2 {
+    contents: int,
+}
+
+impl Trait<int> for S2 {
+    fn new<U>(x: int, _: U) -> S2 {
+        S2 {
+            contents: x,
+        }
+    }
+}
+
+fn main() {
+    let _ = S::new::<int,float>(1, 1.0);    //~ ERROR the impl referenced by this path has 1 type parameter, but 0 type parameters were supplied
+    let _ = S::<'self,int>::new::<float>(1, 1.0);  //~ ERROR this impl has no lifetime parameter
+    let _: S2 = Trait::new::<int,float>(1, 1.0);    //~ ERROR the trait referenced by this path has 1 type parameter, but 0 type parameters were supplied
+    let _: S2 = Trait::<'self,int>::new::<float>(1, 1.0);   //~ ERROR this trait has no lifetime parameter
+}
+
diff --git a/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs b/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs
deleted file mode 100644
index c51cf5b9538..00000000000
--- a/src/test/compile-fail/borrowck-alias-mut-base-ptr.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Test that attempt to alias `&mut` pointer while pointee is borrowed
-// yields an error.
-//
-// Example from src/middle/borrowck/doc.rs
-
-use std::util::swap;
-
-fn foo(t0: &mut int) {
-    let p: &int = &*t0; // Freezes `*t0`
-    let q: &const &mut int = &const t0; //~ ERROR cannot borrow `t0`
-    **q = 22; //~ ERROR cannot assign to an `&mut` in a `&const` pointer
-}
-
-fn main() {
-}
\ No newline at end of file
diff --git a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
index 7e9c298ba47..843b5436d84 100644
--- a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
+++ b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
@@ -11,16 +11,6 @@ fn foo(t0: & &mut int) {
     **t1 = 22; //~ ERROR cannot assign
 }
 
-fn foo2(t0: &const &mut int) {
-    // Note: reborrowing from an &const actually yields two errors, since it
-    // is unsafe in two ways: we can't control the aliasing, and we can't
-    // control the mutation.
-    let t1 = t0;
-    let p: &int = &**t0; //~ ERROR cannot borrow an `&mut` in a `&const` pointer
-    //~^ ERROR unsafe borrow of aliasable, const value
-    **t1 = 22; //~ ERROR cannot assign
-}
-
 fn foo3(t0: &mut &mut int) {
     let t1 = &mut *t0;
     let p: &int = &**t0; //~ ERROR cannot borrow
@@ -28,4 +18,4 @@ fn foo3(t0: &mut &mut int) {
 }
 
 fn main() {
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs
index bd87a57af25..c004b3d0e54 100644
--- a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs
+++ b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs
@@ -13,8 +13,7 @@
 use std::hashmap::HashMap;
 
 fn main() {
-    let mut buggy_map :HashMap<uint, &uint> =
-      HashMap::new::<uint, &uint>();
+    let mut buggy_map: HashMap<uint, &uint> = HashMap::new();
     buggy_map.insert(42, &*~1); //~ ERROR borrowed value does not live long enough
 
     // but it is ok if we use a temporary
diff --git a/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs b/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs
index 0aa7cbf50b7..537e52120d9 100644
--- a/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs
+++ b/src/test/compile-fail/borrowck-call-method-from-mut-aliasable.rs
@@ -14,29 +14,18 @@ struct Foo {
 
 impl Foo {
     pub fn f(&self) {}
-    pub fn g(&const self) {}
     pub fn h(&mut self) {}
 }
 
 fn a(x: &mut Foo) {
     x.f();
-    x.g();
     x.h();
 }
 
 fn b(x: &Foo) {
     x.f();
-    x.g();
     x.h(); //~ ERROR cannot borrow
 }
 
-fn c(x: &const Foo) {
-    x.f(); //~ ERROR cannot borrow
-    //~^ ERROR unsafe borrow
-    x.g();
-    x.h(); //~ ERROR cannot borrow
-    //~^ ERROR unsafe borrow
-}
-
 fn main() {
 }
diff --git a/src/test/compile-fail/borrowck-lend-flow.rs b/src/test/compile-fail/borrowck-lend-flow.rs
index 59cac0c5d95..ea840a28b4e 100644
--- a/src/test/compile-fail/borrowck-lend-flow.rs
+++ b/src/test/compile-fail/borrowck-lend-flow.rs
@@ -32,14 +32,6 @@ fn pre_freeze() {
     borrow_mut(v); //~ ERROR cannot borrow
 }
 
-fn pre_const() {
-    // In this instance, the freeze starts before the mut borrow.
-
-    let mut v = ~3;
-    let _w = &const v;
-    borrow_mut(v);
-}
-
 fn post_freeze() {
     // In this instance, the const alias starts after the borrow.
 
diff --git a/src/test/compile-fail/borrowck-loan-vec-content.rs b/src/test/compile-fail/borrowck-loan-vec-content.rs
index 6a8e64377aa..8a4a2cdedb2 100644
--- a/src/test/compile-fail/borrowck-loan-vec-content.rs
+++ b/src/test/compile-fail/borrowck-loan-vec-content.rs
@@ -29,16 +29,5 @@ fn has_mut_vec_but_tries_to_change_it() {
     }
 }
 
-fn takes_const_elt(_v: &const int, f: &fn()) {
-    f();
-}
-
-fn has_mut_vec_and_tries_to_change_it() {
-    let mut v = ~[1, 2, 3];
-    do takes_const_elt(&const v[0]) {
-        v[1] = 4;
-    }
-}
-
 fn main() {
 }
diff --git a/src/test/compile-fail/borrowck-pat-by-value-binding.rs b/src/test/compile-fail/borrowck-pat-by-value-binding.rs
deleted file mode 100644
index e77f5245d7d..00000000000
--- a/src/test/compile-fail/borrowck-pat-by-value-binding.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn process<T>(_t: T) {}
-
-fn match_const_opt_by_mut_ref(v: &const Option<int>) {
-    match *v {
-      Some(ref mut i) => process(i), //~ ERROR cannot borrow
-        //~^ ERROR unsafe borrow of aliasable, const value
-      None => ()
-    }
-}
-
-fn match_const_opt_by_const_ref(v: &const Option<int>) {
-    match *v {
-      Some(ref const i) => process(i),
-        //~^ ERROR unsafe borrow of aliasable, const value
-      None => ()
-    }
-}
-
-fn match_const_opt_by_imm_ref(v: &const Option<int>) {
-    match *v {
-      Some(ref i) => process(i), //~ ERROR cannot borrow
-        //~^ ERROR unsafe borrow of aliasable, const value
-      None => ()
-    }
-}
-
-fn match_const_opt_by_value(v: &const Option<int>) {
-    match *v {
-      Some(i) => process(i),
-      None => ()
-    }
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/borrowck-uniq-via-lend.rs b/src/test/compile-fail/borrowck-uniq-via-lend.rs
index 43459acaaf1..c87428cd300 100644
--- a/src/test/compile-fail/borrowck-uniq-via-lend.rs
+++ b/src/test/compile-fail/borrowck-uniq-via-lend.rs
@@ -35,12 +35,6 @@ fn aliased_imm() {
     borrow(v);
 }
 
-fn aliased_const() {
-    let mut v = ~3;
-    let _w = &const v;
-    borrow(v);
-}
-
 fn aliased_mut() {
     let mut v = ~3;
     let _w = &mut v;
diff --git a/src/test/compile-fail/fn-variance-3.rs b/src/test/compile-fail/fn-variance-3.rs
index 630eb4b538d..e42c6b658e4 100644
--- a/src/test/compile-fail/fn-variance-3.rs
+++ b/src/test/compile-fail/fn-variance-3.rs
@@ -23,13 +23,10 @@ fn main() {
 
     // @int <: X
     //
-    // This constraint forces X to be
-    // @const int.
-    r(@3);
+    // Here the type check fails because @const is gone and there is no
+    // supertype.
+    r(@3);  //~ ERROR mismatched types
 
-    // Here the type check succeeds but the
-    // mutability check will fail, because the
-    // type of r has been inferred to be
-    // fn(@const int) -> @const int
-    *r(@mut 3) = 4; //~ ERROR cannot assign to const dereference of @ pointer
+    // Here the type check succeeds.
+    *r(@mut 3) = 4;
 }
diff --git a/src/test/compile-fail/issue-3969.rs b/src/test/compile-fail/issue-3969.rs
deleted file mode 100644
index b60a54a44bb..00000000000
--- a/src/test/compile-fail/issue-3969.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Bike {
-    name: ~str,
-}
-
-trait BikeMethods {
-    fn woops(&const self) -> ~str;
-}
-
-impl BikeMethods for Bike {
-    fn woops() -> ~str { ~"foo" }
-    //~^ ERROR has a `&const self` declaration in the trait, but not in the impl
-}
-
-pub fn main() {
-}
diff --git a/src/test/compile-fail/issue-4096.rs b/src/test/compile-fail/issue-4096.rs
deleted file mode 100644
index 3f1172b6de8..00000000000
--- a/src/test/compile-fail/issue-4096.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub trait Nummy {
-    fn from_inty<T>() -> Self;
-}
-
-impl Nummy for float {
-    fn from_inty<T>() -> float { 0.0 }
-}
-
-fn main() {
-    let _1:float = Nummy::from_inty::<int>();  //~ ERROR not enough type
-    //~^ NOTE Static methods have an extra implicit type parameter
-}
diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs
index f6fd8e29a4f..19423c6690f 100644
--- a/src/test/compile-fail/map-types.rs
+++ b/src/test/compile-fail/map-types.rs
@@ -14,8 +14,8 @@ use std::hashmap::HashMap;
 // Test that trait types printed in error msgs include the type arguments.
 
 fn main() {
-    let x: @Map<~str, ~str> = @HashMap::new::<~str, ~str>() as
-        @Map<~str, ~str>;
+    let x: @HashMap<~str, ~str> = @HashMap::new();
+    let x: @Map<~str, ~str> = x as @Map<~str, ~str>;
     let y: @Map<uint, ~str> = @x;
     //~^ ERROR expected trait std::container::Map but found @-ptr
 }
diff --git a/src/test/compile-fail/mutable-huh-ptr-assign.rs b/src/test/compile-fail/mutable-huh-ptr-assign.rs
deleted file mode 100644
index 4460da72e20..00000000000
--- a/src/test/compile-fail/mutable-huh-ptr-assign.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-extern mod extra;
-
-fn main() {
-    unsafe fn f(v: *const int) {
-        *v = 1 //~ ERROR cannot assign
-    }
-
-    unsafe {
-        let mut a = 0;
-        let v = &mut a;
-        f(v);
-    }
-}
diff --git a/src/test/compile-fail/prim-with-args.rs b/src/test/compile-fail/prim-with-args.rs
index 40d5a441241..e60fbf4fc49 100644
--- a/src/test/compile-fail/prim-with-args.rs
+++ b/src/test/compile-fail/prim-with-args.rs
@@ -23,17 +23,17 @@ let x: u64<int>; //~ ERROR type parameters are not allowed on this type
 let x: float<int>; //~ ERROR type parameters are not allowed on this type
 let x: char<int>; //~ ERROR type parameters are not allowed on this type
 
-let x: int<'static>; //~ ERROR region parameters are not allowed on this type
-let x: i8<'static>; //~ ERROR region parameters are not allowed on this type
-let x: i16<'static>; //~ ERROR region parameters are not allowed on this type
-let x: i32<'static>; //~ ERROR region parameters are not allowed on this type
-let x: i64<'static>; //~ ERROR region parameters are not allowed on this type
-let x: uint<'static>; //~ ERROR region parameters are not allowed on this type
-let x: u8<'static>; //~ ERROR region parameters are not allowed on this type
-let x: u16<'static>; //~ ERROR region parameters are not allowed on this type
-let x: u32<'static>; //~ ERROR region parameters are not allowed on this type
-let x: u64<'static>; //~ ERROR region parameters are not allowed on this type
-let x: float<'static>; //~ ERROR region parameters are not allowed on this type
-let x: char<'static>; //~ ERROR region parameters are not allowed on this type
+let x: int<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: i8<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: i16<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: i32<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: i64<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: uint<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: u8<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: u16<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: u32<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: u64<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: float<'static>; //~ ERROR lifetime parameters are not allowed on this type
+let x: char<'static>; //~ ERROR lifetime parameters are not allowed on this type
 
 }
diff --git a/src/test/compile-fail/private-variant-xc.rs b/src/test/compile-fail/private-variant-xc.rs
index 9db023a779b..c3946b33010 100644
--- a/src/test/compile-fail/private-variant-xc.rs
+++ b/src/test/compile-fail/private-variant-xc.rs
@@ -1,4 +1,5 @@
 // aux-build:private_variant_xc.rs
+// xfail-test
 
 extern mod private_variant_xc;
 
diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs
index ab2ac6cc0e5..ab365c1bf6f 100644
--- a/src/test/compile-fail/regions-bounds.rs
+++ b/src/test/compile-fail/regions-bounds.rs
@@ -25,8 +25,4 @@ fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> {
     //~^ ERROR cannot infer an appropriate lifetime
 }
 
-fn a_fn4<'a,'b>() {
-    let _: int<'a> = 1; //~ ERROR region parameters are not allowed on this type
-}
-
 fn main() { }
diff --git a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs
index 65fbbfc6e19..351daf461d2 100644
--- a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs
+++ b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs
@@ -26,13 +26,6 @@ fn matcher2(x: opts) {
     }
 }
 
-fn matcher3(x: opts) {
-    match x {
-      a(ref mut i) | b(ref const i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
-      c(_) => {}
-    }
-}
-
 fn matcher4(x: opts) {
     match x {
       a(ref mut i) | b(ref i) => {} //~ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
diff --git a/src/test/compile-fail/static-method-privacy.rs b/src/test/compile-fail/static-method-privacy.rs
index 0fd82b5ace3..b637037f60e 100644
--- a/src/test/compile-fail/static-method-privacy.rs
+++ b/src/test/compile-fail/static-method-privacy.rs
@@ -6,5 +6,5 @@ mod a {
 }
 
 fn main() {
-    let _ = a::S::new();    //~ ERROR function `new` is private
+    let _ = a::S::new();    //~ ERROR method `new` is private
 }
diff --git a/src/test/compile-fail/xc-private-method.rs b/src/test/compile-fail/xc-private-method.rs
index 8314755af3b..371bac7a902 100644
--- a/src/test/compile-fail/xc-private-method.rs
+++ b/src/test/compile-fail/xc-private-method.rs
@@ -7,10 +7,10 @@ fn main() {
     // normal method on struct
     let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct();  //~ ERROR method `meth_struct` is private
     // static method on struct
-    let _ = xc_private_method_lib::Struct::static_meth_struct();  //~ ERROR function `static_meth_struct` is private
+    let _ = xc_private_method_lib::Struct::static_meth_struct();  //~ ERROR method `static_meth_struct` is private
 
     // normal method on enum
     let _ = xc_private_method_lib::Variant1(20).meth_enum();  //~ ERROR method `meth_enum` is private
     // static method on enum
-    let _ = xc_private_method_lib::Enum::static_meth_enum();  //~ ERROR function `static_meth_enum` is private
+    let _ = xc_private_method_lib::Enum::static_meth_enum();  //~ ERROR method `static_meth_enum` is private
 }
diff --git a/src/test/debug-info/generic-trait-generic-static-default-method.rs b/src/test/debug-info/generic-trait-generic-static-default-method.rs
index 2ade9df4890..9dd6d1ef173 100644
--- a/src/test/debug-info/generic-trait-generic-static-default-method.rs
+++ b/src/test/debug-info/generic-trait-generic-static-default-method.rs
@@ -1,3 +1,5 @@
+// xfail-test
+
 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
diff --git a/src/test/debug-info/trait-generic-static-default-method.rs b/src/test/debug-info/trait-generic-static-default-method.rs
index acdb07c7cb2..2d666bf4cf5 100644
--- a/src/test/debug-info/trait-generic-static-default-method.rs
+++ b/src/test/debug-info/trait-generic-static-default-method.rs
@@ -1,3 +1,5 @@
+// xfail-test
+
 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
diff --git a/src/test/run-pass/auto-ref-slice-plus-ref.rs b/src/test/run-pass/auto-ref-slice-plus-ref.rs
index 58a477900c3..d35341516f2 100644
--- a/src/test/run-pass/auto-ref-slice-plus-ref.rs
+++ b/src/test/run-pass/auto-ref-slice-plus-ref.rs
@@ -13,17 +13,14 @@
 
 trait MyIter {
     fn test_imm(&self);
-    fn test_const(&const self);
 }
 
 impl<'self> MyIter for &'self [int] {
     fn test_imm(&self) { assert_eq!(self[0], 1) }
-    fn test_const(&const self) { assert_eq!(self[0], 1) }
 }
 
 impl<'self> MyIter for &'self str {
     fn test_imm(&self) { assert_eq!(*self, "test") }
-    fn test_const(&const self) { assert_eq!(self[0], 't' as u8) }
 }
 
 pub fn main() {
@@ -40,15 +37,6 @@ pub fn main() {
 
     // XXX: Other types of mutable vecs don't currently exist
 
-    ([1]).test_const();
-    (~[1]).test_const();
-    (@[1]).test_const();
-    (&[1]).test_const();
-    ("test").test_const();
-    (~"test").test_const();
-    (@"test").test_const();
-    (&"test").test_const();
-
     // NB: We don't do this double autoreffing for &mut self because that would
     // allow creating a mutable pointer to a temporary, which would be a source
     // of confusion
diff --git a/src/test/run-pass/autoderef-and-borrow-method-receiver.rs b/src/test/run-pass/autoderef-and-borrow-method-receiver.rs
index b00d8980c69..fc643ec5940 100644
--- a/src/test/run-pass/autoderef-and-borrow-method-receiver.rs
+++ b/src/test/run-pass/autoderef-and-borrow-method-receiver.rs
@@ -13,7 +13,7 @@ struct Foo {
 }
 
 impl Foo {
-    pub fn f(&const self) {}
+    pub fn f(&self) {}
 }
 
 fn g(x: &mut Foo) {
diff --git a/src/test/compile-fail/borrowck-pat-enum.rs b/src/test/run-pass/borrowck-pat-enum.rs
index f1cca89b227..f320de39c8c 100644
--- a/src/test/compile-fail/borrowck-pat-enum.rs
+++ b/src/test/run-pass/borrowck-pat-enum.rs
@@ -1,3 +1,5 @@
+// xfail-pretty
+
 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -24,32 +26,9 @@ fn match_ref_unused(v: Option<int>) {
     }
 }
 
-fn match_const_reg(v: &const Option<int>) -> int {
-    match *v {
-      Some(ref i) => {*i} //~ ERROR cannot borrow
-        //~^ ERROR unsafe borrow
-      None => {0}
-    }
-}
-
 fn impure(_i: int) {
 }
 
-fn match_const_reg_unused(v: &const Option<int>) {
-    match *v {
-      Some(_) => {impure(0)} // OK because nothing is captured
-      None => {}
-    }
-}
-
-fn match_const_reg_impure(v: &const Option<int>) {
-    match *v {
-      Some(ref i) => {impure(*i)} //~ ERROR cannot borrow
-        //~^ ERROR unsafe borrow
-      None => {}
-    }
-}
-
 fn match_imm_reg(v: &Option<int>) {
     match *v {
       Some(ref i) => {impure(*i)} // OK because immutable
diff --git a/src/test/compile-fail/borrowck-uniq-via-ref.rs b/src/test/run-pass/borrowck-uniq-via-ref.rs
index 8bf627d9919..44f3a8f518a 100644
--- a/src/test/compile-fail/borrowck-uniq-via-ref.rs
+++ b/src/test/run-pass/borrowck-uniq-via-ref.rs
@@ -25,7 +25,6 @@ struct Innermost {
 }
 
 fn borrow(_v: &int) {}
-fn borrow_const(_v: &const int) {}
 
 fn box_mut(v: &mut ~int) {
     borrow(*v); // OK: &mut -> &imm
@@ -51,17 +50,5 @@ fn box_imm_recs(v: &Outer) {
     borrow(v.f.g.h); // OK
 }
 
-fn box_const(v: &const ~int) {
-    borrow_const(*v); //~ ERROR unsafe borrow
-}
-
-fn box_const_rec(v: &const Rec) {
-    borrow_const(v.f); //~ ERROR unsafe borrow
-}
-
-fn box_const_recs(v: &const Outer) {
-    borrow_const(v.f.g.h); //~ ERROR unsafe borrow
-}
-
 fn main() {
 }
diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs
index 01907da38ad..03dd33b08e2 100644
--- a/src/test/run-pass/class-impl-very-parameterized-trait.rs
+++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs
@@ -49,8 +49,8 @@ impl<T> cat<T> {
 }
 
 impl<T> Container for cat<T> {
-    fn len(&const self) -> uint { self.meows as uint }
-    fn is_empty(&const self) -> bool { self.meows == 0 }
+    fn len(&self) -> uint { self.meows as uint }
+    fn is_empty(&self) -> bool { self.meows == 0 }
 }
 
 impl<T> Mutable for cat<T> {
diff --git a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs
index 5525062581c..52fa1399363 100644
--- a/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs
+++ b/src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs
@@ -3,14 +3,14 @@ struct SpeechMaker {
 }
 
 impl SpeechMaker {
-    pub fn how_many(&const self) -> uint { self.speeches }
+    pub fn how_many(&self) -> uint { self.speeches }
 }
 
-fn foo(speaker: &const SpeechMaker) -> uint {
+fn foo(speaker: &SpeechMaker) -> uint {
     speaker.how_many() + 33
 }
 
 pub fn main() {
     let lincoln = SpeechMaker {speeches: 22};
-    assert_eq!(foo(&const lincoln), 55);
+    assert_eq!(foo(&lincoln), 55);
 }
diff --git a/src/test/run-pass/const-vec-syntax.rs b/src/test/run-pass/const-vec-syntax.rs
index 625f6ec30cc..84ee54cfdde 100644
--- a/src/test/run-pass/const-vec-syntax.rs
+++ b/src/test/run-pass/const-vec-syntax.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(_: &const [int]) {}
+fn f(_: &[int]) {}
 
 pub fn main() {
     let v = [ 1, 2, 3 ];
diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs
index 21956ac24ee..aba23e53282 100644
--- a/src/test/run-pass/deriving-zero.rs
+++ b/src/test/run-pass/deriving-zero.rs
@@ -36,5 +36,6 @@ struct Lots {
 }
 
 fn main() {
-    assert!(Zero::zero::<Lots>().is_zero());
+    let lots: Lots = Zero::zero();
+    assert!(lots.is_zero());
 }
diff --git a/src/test/run-pass/float-nan.rs b/src/test/run-pass/float-nan.rs
index 29a180db185..d59b8c77d00 100644
--- a/src/test/run-pass/float-nan.rs
+++ b/src/test/run-pass/float-nan.rs
@@ -13,11 +13,12 @@ extern mod extra;
 use std::num::Float;
 
 pub fn main() {
-  let nan = Float::NaN::<float>();
+  let nan: float = Float::NaN();
   assert!((nan).is_NaN());
 
-  let inf = Float::infinity::<float>();
-  assert_eq!(-inf, Float::neg_infinity::<float>());
+  let inf: float = Float::infinity();
+  let neg_inf: float = Float::neg_infinity();
+  assert_eq!(-inf, neg_inf);
 
   assert!( nan !=  nan);
   assert!( nan != -nan);
diff --git a/src/test/run-pass/issue-3026.rs b/src/test/run-pass/issue-3026.rs
index a4b37f0ba0f..ce471e5c827 100644
--- a/src/test/run-pass/issue-3026.rs
+++ b/src/test/run-pass/issue-3026.rs
@@ -13,7 +13,7 @@
 use std::hashmap::HashMap;
 
 pub fn main() {
-    let mut buggy_map: HashMap<uint, &uint> = HashMap::new::<uint, &uint>();
+    let mut buggy_map: HashMap<uint, &uint> = HashMap::new();
     let x = ~1;
     buggy_map.insert(42, &*x);
 }
diff --git a/src/test/run-pass/issue-6898.rs b/src/test/run-pass/issue-6898.rs
index 2d612bb742e..8e9502d6d49 100644
--- a/src/test/run-pass/issue-6898.rs
+++ b/src/test/run-pass/issue-6898.rs
@@ -1,3 +1,5 @@
+// xfail-test
+
 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
diff --git a/src/test/run-pass/mid-path-type-params.rs b/src/test/run-pass/mid-path-type-params.rs
new file mode 100644
index 00000000000..1bc37a035e0
--- /dev/null
+++ b/src/test/run-pass/mid-path-type-params.rs
@@ -0,0 +1,33 @@
+struct S<T> {
+    contents: T,
+}
+
+impl<T> S<T> {
+    fn new<U>(x: T, _: U) -> S<T> {
+        S {
+            contents: x,
+        }
+    }
+}
+
+trait Trait<T> {
+    fn new<U>(x: T, y: U) -> Self;
+}
+
+struct S2 {
+    contents: int,
+}
+
+impl Trait<int> for S2 {
+    fn new<U>(x: int, _: U) -> S2 {
+        S2 {
+            contents: x,
+        }
+    }
+}
+
+fn main() {
+    let _ = S::<int>::new::<float>(1, 1.0);
+    let _: S2 = Trait::<int>::new::<float>(1, 1.0);
+}
+
diff --git a/src/test/run-pass/objects-owned-object-borrowed-method-header.rs b/src/test/run-pass/objects-owned-object-borrowed-method-header.rs
index 23c271f53ca..baef20944f7 100644
--- a/src/test/run-pass/objects-owned-object-borrowed-method-header.rs
+++ b/src/test/run-pass/objects-owned-object-borrowed-method-header.rs
@@ -1,3 +1,5 @@
+// xfail-pretty
+
 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs
index 1360b76653c..a4510ef70e1 100644
--- a/src/test/run-pass/trait-bounds-in-arc.rs
+++ b/src/test/run-pass/trait-bounds-in-arc.rs
@@ -1,3 +1,5 @@
+// xfail-pretty
+
 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs
index 0c334909b25..baf4cf45b3c 100644
--- a/src/test/run-pass/trait-default-method-xc.rs
+++ b/src/test/run-pass/trait-default-method-xc.rs
@@ -59,7 +59,7 @@ fn main () {
 
     assert_eq!(0i.thing(3.14, 1), (3.14, 1));
     assert_eq!(B::staticthing(&0i, 3.14, 1), (3.14, 1));
-    assert_eq!(B::staticthing::<float, int, int>(&0i, 3.14, 1), (3.14, 1));
+    assert_eq!(B::<float>::staticthing::<int>(&0i, 3.14, 1), (3.14, 1));
 
     assert_eq!(g(0i, 3.14, 1), (3.14, 1));
     assert_eq!(g(false, 3.14, 1), (3.14, 1));
diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs
index e95b80447e4..5ac26e65d88 100644
--- a/src/test/run-pass/trait-static-method-overwriting.rs
+++ b/src/test/run-pass/trait-static-method-overwriting.rs
@@ -14,7 +14,7 @@ mod base {
     use std::io;
 
     pub trait HasNew<T> {
-        fn new() -> T;
+        fn new() -> Self;
     }
 
     pub struct Foo {
@@ -41,6 +41,6 @@ mod base {
 }
 
 pub fn main() {
-    let _f: base::Foo = base::HasNew::new::<base::Foo, base::Foo>();
-    let _b: base::Bar = base::HasNew::new::<base::Bar, base::Bar>();
+    let _f: base::Foo = base::HasNew::<base::Foo>::new();
+    let _b: base::Bar = base::HasNew::<base::Bar>::new();
 }