about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/tutorial-container.md12
-rw-r--r--mk/target.mk2
-rw-r--r--mk/tests.mk14
-rw-r--r--mk/tools.mk26
-rw-r--r--src/compiletest/runtest.rs2
-rw-r--r--src/etc/emacs/Makefile14
-rw-r--r--src/etc/emacs/README.md35
-rw-r--r--src/etc/emacs/cm-mode.el194
-rw-r--r--src/etc/emacs/rust-mode.el523
-rw-r--r--src/libextra/num/bigint.rs5
-rw-r--r--src/libextra/num/rational.rs19
-rw-r--r--src/librustc/metadata/common.rs1
-rw-r--r--src/librustc/metadata/csearch.rs9
-rw-r--r--src/librustc/metadata/decoder.rs24
-rw-r--r--src/librustc/metadata/encoder.rs21
-rw-r--r--src/librustc/metadata/tydecode.rs20
-rw-r--r--src/librustc/metadata/tyencode.rs17
-rw-r--r--src/librustc/middle/astencode.rs113
-rw-r--r--src/librustc/middle/check_match.rs23
-rw-r--r--src/librustc/middle/kind.rs3
-rw-r--r--src/librustc/middle/lang_items.rs4
-rw-r--r--src/librustc/middle/lint.rs45
-rw-r--r--src/librustc/middle/privacy.rs7
-rw-r--r--src/librustc/middle/subst.rs41
-rw-r--r--src/librustc/middle/trans/_match.rs4
-rw-r--r--src/librustc/middle/trans/adt.rs62
-rw-r--r--src/librustc/middle/trans/base.rs12
-rw-r--r--src/librustc/middle/trans/callee.rs67
-rw-r--r--src/librustc/middle/trans/common.rs60
-rw-r--r--src/librustc/middle/trans/consts.rs2
-rw-r--r--src/librustc/middle/trans/controlflow.rs66
-rw-r--r--src/librustc/middle/trans/expr.rs4
-rw-r--r--src/librustc/middle/trans/meth.rs64
-rw-r--r--src/librustc/middle/trans/monomorphize.rs9
-rw-r--r--src/librustc/middle/trans/reflect.rs2
-rw-r--r--src/librustc/middle/trans/type_of.rs4
-rw-r--r--src/librustc/middle/trans/type_use.rs5
-rw-r--r--src/librustc/middle/ty.rs149
-rw-r--r--src/librustc/middle/typeck/astconv.rs43
-rw-r--r--src/librustc/middle/typeck/check/method.rs203
-rw-r--r--src/librustc/middle/typeck/check/mod.rs82
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs588
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs5
-rw-r--r--src/librustc/middle/typeck/coherence.rs23
-rw-r--r--src/librustc/middle/typeck/collect.rs10
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs89
-rw-r--r--src/librustc/middle/typeck/infer/mod.rs5
-rw-r--r--src/librustc/middle/typeck/mod.rs51
-rw-r--r--src/librustc/middle/typeck/rscope.rs6
-rw-r--r--src/librustc/util/ppaux.rs54
-rw-r--r--src/libstd/at_vec.rs59
-rw-r--r--src/libstd/bool.rs15
-rw-r--r--src/libstd/cast.rs4
-rw-r--r--src/libstd/cleanup.rs31
-rw-r--r--src/libstd/cmp.rs7
-rw-r--r--src/libstd/gc.rs16
-rw-r--r--src/libstd/iterator.rs21
-rw-r--r--src/libstd/managed.rs23
-rw-r--r--src/libstd/option.rs35
-rw-r--r--src/libstd/reflect.rs4
-rw-r--r--src/libstd/repr.rs38
-rw-r--r--src/libstd/rt/borrowck.rs32
-rw-r--r--src/libstd/rt/global_heap.rs8
-rw-r--r--src/libstd/rt/local_heap.rs6
-rw-r--r--src/libstd/rt/sched.rs4
-rw-r--r--src/libstd/rt/task.rs2
-rw-r--r--src/libstd/str.rs60
-rw-r--r--src/libstd/sys.rs7
-rw-r--r--src/libstd/task/local_data_priv.rs4
-rw-r--r--src/libstd/unstable/atomics.rs186
-rw-r--r--src/libstd/unstable/mod.rs1
-rw-r--r--src/libstd/unstable/raw.rs61
-rw-r--r--src/libstd/vec.rs145
-rw-r--r--src/libsyntax/opt_vec.rs1
-rw-r--r--src/libsyntax/parse/mod.rs6
-rw-r--r--src/libsyntax/util/parser_testing.rs27
-rw-r--r--src/rt/rust_task.cpp2
-rw-r--r--src/snapshots.txt8
-rw-r--r--src/test/auxiliary/issue_3979_traits.rs7
-rw-r--r--src/test/auxiliary/no_std_crate.rs3
-rw-r--r--src/test/compile-fail/issue-6804.rs21
-rw-r--r--src/test/compile-fail/lint-default-methods.rs7
-rw-r--r--src/test/compile-fail/lint-non-camel-case-types.rs12
-rw-r--r--src/test/run-pass/default-method-supertrait-vtable.rs36
-rw-r--r--src/test/run-pass/deriving-zero.rs1
-rw-r--r--src/test/run-pass/enum-discr.rs20
-rw-r--r--src/test/run-pass/issue-3168.rs1
-rw-r--r--src/test/run-pass/issue-3176.rs1
-rw-r--r--src/test/run-pass/issue-3979-2.rs2
-rw-r--r--src/test/run-pass/issue-3979-generics.rs12
-rw-r--r--src/test/run-pass/issue-3979-xcrate.rs2
-rw-r--r--src/test/run-pass/issue-3979.rs2
-rw-r--r--src/test/run-pass/issue-7712.rs4
-rw-r--r--src/test/run-pass/no-std-xcrate.rs (renamed from src/test/compile-fail/issue-2467.rs)15
-rw-r--r--src/test/run-pass/no-std-xcrate2.rs35
-rw-r--r--src/test/run-pass/pipe-sleep.rs1
-rw-r--r--src/test/run-pass/reflect-visit-data.rs4
-rw-r--r--src/test/run-pass/supertrait-default-generics.rs42
-rw-r--r--src/test/run-pass/tag-variant-disr-type-mismatch.rs (renamed from src/test/compile-fail/tag-variant-disr-type-mismatch.rs)2
-rw-r--r--src/test/run-pass/unit-like-struct-drop-run.rs1
100 files changed, 2058 insertions, 1829 deletions
diff --git a/doc/tutorial-container.md b/doc/tutorial-container.md
index 1b195e99979..148afb4bda9 100644
--- a/doc/tutorial-container.md
+++ b/doc/tutorial-container.md
@@ -108,12 +108,14 @@ impl Iterator<int> for ZeroStream {
 ## Container iterators
 
 Containers implement iteration over the contained elements by returning an
-iterator object. For example, vector slices have four iterators available:
+iterator object. For example, vector slices several iterators available:
 
-* `vector.iter()`, for immutable references to the elements
-* `vector.mut_iter()`, for mutable references to the elements
-* `vector.rev_iter()`, for immutable references to the elements in reverse order
-* `vector.mut_rev_iter()`, for mutable references to the elements in reverse order
+* `iter()` and `rev_iter()`, for immutable references to the elements
+* `mut_iter()` and `mut_rev_iter()`, for mutable references to the elements
+* `consume_iter()` and `consume_rev_iter`, to move the elements out by-value
+
+A typical mutable container will implement at least `iter()`, `mut_iter()` and
+`consume_iter()` along with the reverse variants if it maintains an order.
 
 ### Freezing
 
diff --git a/mk/target.mk b/mk/target.mk
index 75482aed0d8..b9221a56b9d 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -84,6 +84,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(3)): \
 $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)): CFG_COMPILER_TRIPLE = $(2)
 $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)):		\
 		$$(COMPILER_CRATE) $$(COMPILER_INPUTS)		\
+		$$(TSREQ$(1)_T_$(2)_H_$(3)) \
                 $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)) \
                 $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(3)) \
 		| $$(TLIB$(1)_T_$(2)_H_$(3))/
@@ -94,6 +95,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)):		\
 
 $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)):			\
 		$$(DRIVER_CRATE)				\
+		$$(TSREQ$(1)_T_$(2)_H_$(3)) \
 		$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)) \
 		| $$(TBIN$(1)_T_$(2)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
diff --git a/mk/tests.mk b/mk/tests.mk
index 770e7280491..9e0ccb5dbee 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -319,18 +319,21 @@ endif
 
 $(3)/stage$(1)/test/stdtest-$(2)$$(X_$(2)):			\
 		$$(STDLIB_CRATE) $$(STDLIB_INPUTS)	\
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(STDTESTDEP_$(1)_$(2)_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
 $(3)/stage$(1)/test/extratest-$(2)$$(X_$(2)):			\
 		$$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS)	\
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(STDTESTDEP_$(1)_$(2)_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
 $(3)/stage$(1)/test/syntaxtest-$(2)$$(X_$(2)):			\
 		$$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS)	\
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(STDTESTDEP_$(1)_$(2)_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
@@ -338,6 +341,7 @@ $(3)/stage$(1)/test/syntaxtest-$(2)$$(X_$(2)):			\
 $(3)/stage$(1)/test/rustctest-$(2)$$(X_$(2)): CFG_COMPILER_TRIPLE = $(2)
 $(3)/stage$(1)/test/rustctest-$(2)$$(X_$(2)):					\
 		$$(COMPILER_CRATE) $$(COMPILER_INPUTS) \
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_RUSTLLVM_$(2)) \
                 $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2))
 	@$$(call E, compile_and_link: $$@)
@@ -345,24 +349,28 @@ $(3)/stage$(1)/test/rustctest-$(2)$$(X_$(2)):					\
 
 $(3)/stage$(1)/test/rustpkgtest-$(2)$$(X_$(2)):					\
 		$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS)		\
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
 $(3)/stage$(1)/test/rustitest-$(2)$$(X_$(2)):					\
 		$$(RUSTI_LIB) $$(RUSTI_INPUTS)		\
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
 $(3)/stage$(1)/test/rusttest-$(2)$$(X_$(2)):					\
 		$$(RUST_LIB) $$(RUST_INPUTS)		\
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
 $(3)/stage$(1)/test/rustdoctest-$(2)$$(X_$(2)):					\
 		$$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS)		\
+		$$(SREQ$(1)_T_$(2)_H_$(3)) \
 		$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
@@ -537,6 +545,10 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \
 
 # Rules for the cfail/rfail/rpass/bench/perf test runner
 
+# The tests select when to use debug configuration on their own;
+# remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898).
+CTEST_RUSTC_FLAGS = $$(subst --cfg debug,,$$(CFG_RUSTC_FLAGS))
+
 CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) :=						\
 		--compile-lib-path $$(HLIB$(1)_H_$(3))				\
         --run-lib-path $$(TLIB$(1)_T_$(2)_H_$(3))			\
@@ -548,7 +560,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) :=						\
         --target $(2)                                       \
         --adb-path=$(CFG_ADB)                          \
         --adb-test-dir=$(CFG_ADB_TEST_DIR)                  \
-        --rustcflags "$(RUSTC_FLAGS_$(2)) $$(CFG_RUSTC_FLAGS) --target=$(2)" \
+        --rustcflags "$(RUSTC_FLAGS_$(2)) $$(CTEST_RUSTC_FLAGS) --target=$(2)" \
         $$(CTEST_TESTARGS)
 
 CTEST_DEPS_rpass_$(1)-T-$(2)-H-$(3) = $$(RPASS_TESTS)
diff --git a/mk/tools.mk b/mk/tools.mk
index 5afabbcb336..56aad4f10a2 100644
--- a/mk/tools.mk
+++ b/mk/tools.mk
@@ -37,18 +37,14 @@ define TOOLS_STAGE_N_TARGET
 
 $$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)):			\
 		$$(COMPILETEST_CRATE) $$(COMPILETEST_INPUTS)	\
-		$$(TSREQ$(1)_T_$(4)_H_$(3))						\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4))      \
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))    \
+		$$(SREQ$(1)_T_$(4)_H_$(3))			\
 		| $$(TBIN$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$<
 
 $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)):		\
 		$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS)		    \
-		$$(TSREQ$(1)_T_$(4)_H_$(3))					\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4))	\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))	\
+		$$(SREQ$(1)_T_$(4)_H_$(3))			\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) \
 		| $$(TLIB$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
@@ -58,16 +54,15 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)):		\
 
 $$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)):				\
 		$$(DRIVER_CRATE) 							\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)) \
+		$$(TSREQ$(1)_T_$(4)_H_$(3))				\
+		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4))	\
 		| $$(TBIN$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustpkg -o $$@ $$<
 
 $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)):		\
 		$$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS)			\
-		$$(TSREQ$(1)_T_$(4)_H_$(3))					\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4))	\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))	\
+		$$(SREQ$(1)_T_$(4)_H_$(3))			\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) \
 		| $$(TLIB$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
@@ -77,6 +72,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)):		\
 
 $$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)):			\
 		$$(DRIVER_CRATE) 							\
+		$$(TSREQ$(1)_T_$(4)_H_$(3))						\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4))			\
 		| $$(TBIN$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
@@ -84,9 +80,7 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)):			\
 
 $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)):		\
 		$$(RUSTI_LIB) $$(RUSTI_INPUTS)			\
-		$$(TSREQ$(1)_T_$(4)_H_$(3))					\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4))	\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))	\
+		$$(SREQ$(1)_T_$(4)_H_$(3))			\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))	\
 		| $$(TLIB$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
@@ -96,6 +90,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)):		\
 
 $$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)):			\
 		$$(DRIVER_CRATE) 							\
+		$$(TSREQ$(1)_T_$(4)_H_$(3))			\
 		$$(TLIB$(1)_T_$(4)_H_$(4))/$(CFG_LIBRUSTI_$(4)) \
 		| $$(TBIN$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
@@ -103,9 +98,7 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)):			\
 
 $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)):		\
 		$$(RUST_LIB) $$(RUST_INPUTS)			\
-		$$(TSREQ$(1)_T_$(4)_H_$(3))					\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4))	\
-		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))	\
+		$$(SREQ$(1)_T_$(4)_H_$(3))				\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4))	\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4))		\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4))	\
@@ -118,6 +111,7 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)):		\
 
 $$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X_$(4)):			\
 		$$(DRIVER_CRATE) 							\
+		$$(TSREQ$(1)_T_$(4)_H_$(3))			\
 		$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)) \
 		| $$(TBIN$(1)_T_$(4)_H_$(3))/
 	@$$(call E, compile_and_link: $$@)
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 7cd73c82530..4b2f1850b79 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -681,7 +681,7 @@ fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
 }
 
 fn aux_output_dir_name(config: &config, testfile: &Path) -> Path {
-    output_base_name(config, testfile).with_filetype("libaux")
+    Path(output_base_name(config, testfile).to_str() + ".libaux")
 }
 
 fn output_testname(testfile: &Path) -> Path {
diff --git a/src/etc/emacs/Makefile b/src/etc/emacs/Makefile
deleted file mode 100644
index c79e7a9719b..00000000000
--- a/src/etc/emacs/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-E=@echo
-TEMP=temp.el
-
-EMACS ?= emacs
-
-all: $(TEMP)
-	$(EMACS) -batch -q -no-site-file -l ./$(TEMP) -f rustmode-compile
-	rm -f $(TEMP)
-$(TEMP):
-	$(E) '(setq load-path (cons "." load-path))' >> $(TEMP)
-	$(E) '(defun rustmode-compile () (mapcar (lambda (x) (byte-compile-file x))' >> $(TEMP)
-	$(E) ' (list "cm-mode.el" "rust-mode.el")))' >> $(TEMP)
-clean:
-	rm -f *.elc $(TEMP)
diff --git a/src/etc/emacs/README.md b/src/etc/emacs/README.md
index 02c2c248d36..508ac7f1af2 100644
--- a/src/etc/emacs/README.md
+++ b/src/etc/emacs/README.md
@@ -13,21 +13,8 @@ file:
     (add-to-list 'load-path "/path/to/rust-mode/")
     (require 'rust-mode)
 
-Make sure you byte-compile the .el files first, or the mode will be
-painfully slow. There is an included `Makefile` which will do it for
-you, so in the simplest case you can just run `make` and everything
-should Just Work.
-
-If for some reason that doesn't work, you can byte compile manually,
-by pasting this in your `*scratch*` buffer, moving the cursor below
-it, and pressing `C-j`:
-
-    (progn
-      (byte-compile-file "/path/to/rust-mode/cm-mode.el" t)
-      (byte-compile-file "/path/to/rust-mode/rust-mode.el" t))
-
-Rust mode will automatically be associated with .rs and .rc files. To
-enable it explicitly, do `M-x rust-mode`.
+Rust mode will automatically be associated with .rs files. To enable it
+explicitly, do `M-x rust-mode`.
 
 ### package.el installation via Marmalade or MELPA
 
@@ -67,24 +54,6 @@ should upgrade in order to support installation from multiple sources.
 The ELPA archive is deprecated and no longer accepting new packages,
 so the version there (1.7.1) is very outdated.
 
-#### Important
-
-In order to have cm-mode properly initialized after compilation prior
-to rust-mode.el compilation you will need to add these `advices` to
-your init file or if you are a melpa user install the `melpa` package.
-
-```lisp
-(defadvice package-download-tar
-  (after package-download-tar-initialize activate compile)
-  "initialize the package after compilation"
-  (package-initialize))
-
-(defadvice package-download-single
-  (after package-download-single-initialize activate compile)
-  "initialize the package after compilation"
-  (package-initialize))
-```
-
 #### Install rust-mode
 
 From there you can install rust-mode or any other modes by choosing
diff --git a/src/etc/emacs/cm-mode.el b/src/etc/emacs/cm-mode.el
deleted file mode 100644
index 0303f994172..00000000000
--- a/src/etc/emacs/cm-mode.el
+++ /dev/null
@@ -1,194 +0,0 @@
-;;; cm-mode.el --- Wrapper for CodeMirror-style Emacs modes
-
-;; Version: 0.1.0
-;; Author: Mozilla
-;; Url: https://github.com/mozilla/rust
-;; Highlighting is done by running a stateful parser (with first-class
-;; state object) over the buffer, line by line, using the output to
-;; add 'face properties, and storing the parser state at the end of
-;; each line. Indentation is done based on the parser state at the
-;; start of the line.
-
-(eval-when-compile (require 'cl))
-
-;; Mode data structure
-
-(defun make-cm-mode (token &optional start-state copy-state
-                           compare-state indent)
-  (vector token
-          (or start-state (lambda () 'null))
-          (or copy-state 'cm-default-copy-state)
-          (or compare-state 'eq)
-          indent))
-(defmacro cm-mode-token (x) `(aref ,x 0))
-(defmacro cm-mode-start-state (x) `(aref ,x 1))
-(defmacro cm-mode-copy-state (x) `(aref ,x 2))
-(defmacro cm-mode-compare-state (x) `(aref ,x 3))
-(defmacro cm-mode-indent (x) `(aref ,x 4))
-
-(defvar cm-cur-mode nil)
-(defvar cm-worklist nil)
-
-(defun cm-default-copy-state (state)
-  (if (consp state) (copy-sequence state) state))
-
-(defun cm-clear-work-items (from to)
-  (let ((prev-cons nil)
-        (rem cm-worklist))
-    (while rem
-      (let ((pos (marker-position (car rem))))
-        (cond ((or (< pos from) (> pos to)) (setf prev-cons rem))
-              (prev-cons (setf (cdr prev-cons) (cdr rem)))
-              (t (setf cm-worklist (cdr rem))))
-        (setf rem (cdr rem))))))
-
-(defun cm-min-worklist-item ()
-  (let ((rest cm-worklist) (min most-positive-fixnum))
-    (while rest
-      (let ((pos (marker-position (car rest))))
-        (when (< pos min) (setf min pos)))
-      (setf rest (cdr rest)))
-    min))
-
-;; Indentation
-
-(defun cm-indent ()
-  (let (indent-pos)
-    (save-excursion
-      (beginning-of-line)
-      (let* ((buf (current-buffer))
-             (state (cm-preserve-state buf 'cm-state-for-point))
-             (old-indent (current-indentation)))
-        (back-to-indentation)
-        (setf indent-pos (point))
-        (let ((new-indent (funcall (cm-mode-indent cm-cur-mode) state)))
-          (unless (= old-indent new-indent)
-            (indent-line-to new-indent)
-            (setf indent-pos (point))
-            (beginning-of-line)
-            (cm-preserve-state buf
-             (lambda ()
-               (cm-highlight-line state)
-               (when (< (point) (point-max))
-                 (put-text-property (point) (+ (point) 1) 'cm-parse-state state))))))))
-    (when (< (point) indent-pos)
-      (goto-char indent-pos))))
-
-(defun cm-backtrack-to-state ()
-  (let ((backtracked 0)
-        (min-indent most-positive-fixnum)
-        min-indented)
-    (loop
-     (when (= (point) (point-min))
-       (return (funcall (cm-mode-start-state cm-cur-mode))))
-     (let ((st (get-text-property (- (point) 1) 'cm-parse-state)))
-       (when (and st (save-excursion
-                       (backward-char)
-                       (beginning-of-line)
-                       (not (looking-at "[	 ]*$"))))
-         (return (funcall (cm-mode-copy-state cm-cur-mode) st))))
-     (let ((i (current-indentation)))
-       (when (< i min-indent)
-         (setf min-indent i min-indented (point))))
-     (when (> (incf backtracked) 30)
-       (goto-char min-indented)
-       (return (funcall (cm-mode-start-state cm-cur-mode))))
-     (forward-line -1))))
-
-(defun cm-state-for-point ()
-  (let ((pos (point))
-        (state (cm-backtrack-to-state)))
-    (while (< (point) pos)
-      (cm-highlight-line state)
-      (put-text-property (point) (+ (point) 1) 'cm-parse-state
-                         (funcall (cm-mode-copy-state cm-cur-mode) state))
-      (forward-char))
-    state))
-
-;; Highlighting
-
-(defun cm-highlight-line (state)
-  (let ((eol (point-at-eol)))
-    (remove-text-properties (point) eol '(face))
-    (loop
-     (let ((p (point)))
-       (when (= p eol) (return))
-       (let ((style (funcall (cm-mode-token cm-cur-mode) state)))
-         (when (= p (point)) (print (point)) (error "Nothing consumed."))
-         (when (> p eol) (error "Parser moved past EOL"))
-         (when style
-           (put-text-property p (point) 'face style)))))))
-
-(defun cm-find-state-before-point ()
-  (loop
-   (beginning-of-line)
-   (when (= (point) 1)
-     (return (funcall (cm-mode-start-state cm-cur-mode))))
-   (let ((cur (get-text-property (- (point) 1) 'cm-parse-state)))
-     (when cur (return (funcall (cm-mode-copy-state cm-cur-mode) cur))))
-   (backward-char)))
-
-(defun cm-schedule-work (delay)
-  (run-with-idle-timer delay nil 'cm-preserve-state (current-buffer) 'cm-do-some-work))
-
-(defun cm-preserve-state (buffer f &rest args)
-  (with-current-buffer buffer
-    (let ((modified (buffer-modified-p))
-          (buffer-undo-list t)
-          (inhibit-read-only t)
-          (inhibit-point-motion-hooks t)
-          (inhibit-modification-hooks t))
-      (unwind-protect (apply f args)
-        (unless modified
-          (restore-buffer-modified-p nil))))))
-
-(defun cm-do-some-work-inner ()
-  (let ((end-time (time-add (current-time) (list 0 0 500)))
-        (quitting nil))
-    (while (and (not quitting) cm-worklist)
-      (goto-char (cm-min-worklist-item))
-      (let ((state (cm-find-state-before-point))
-            (startpos (point))
-            (timer-idle-list nil))
-        (loop
-         (cm-highlight-line state)
-         (when (= (point) (point-max)) (return))
-         (let ((old (get-text-property (point) 'cm-parse-state)))
-           (when (and old (funcall (cm-mode-compare-state cm-cur-mode) state old))
-             (return))
-           (put-text-property (point) (+ (point) 1) 'cm-parse-state
-                              (funcall (cm-mode-copy-state cm-cur-mode) state)))
-         (when (or (let ((timer-idle-list nil)) (input-pending-p))
-                   (time-less-p end-time (current-time)))
-           (setf quitting t) (return))
-         (forward-char))
-        (cm-clear-work-items startpos (point)))
-      (when quitting
-        (push (copy-marker (+ (point) 1)) cm-worklist)
-        (cm-schedule-work 0.05)))))
-
-(defun cm-do-some-work ()
-  (save-excursion
-    (condition-case cnd (cm-do-some-work-inner)
-      (error (print cnd) (error cnd)))))
-
-(defun cm-after-change-function (from to oldlen)
-  (cm-preserve-state (current-buffer) 'remove-text-properties from to '(cm-parse-state))
-  (push (copy-marker from) cm-worklist)
-  (cm-schedule-work 0.2))
-
-;; Entry function
-
-;;;###autoload
-(defun cm-mode (mode)
-  (set (make-local-variable 'cm-cur-mode) mode)
-  (set (make-local-variable 'cm-worklist) (list (copy-marker 1)))
-  (when (cm-mode-indent mode)
-    (set (make-local-variable 'indent-line-function) 'cm-indent))
-  (add-hook 'after-change-functions 'cm-after-change-function t t)
-  (add-hook 'after-revert-hook (lambda () (cm-after-change-function 1 (point-max) nil)) t t)
-  (cm-schedule-work 0.05))
-
-(provide 'cm-mode)
-
-;;; cm-mode.el ends here
diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el
index a1b8423ae3b..106cdbfd5f4 100644
--- a/src/etc/emacs/rust-mode.el
+++ b/src/etc/emacs/rust-mode.el
@@ -1,331 +1,222 @@
 ;;; rust-mode.el --- A major emacs mode for editing Rust source code
 
-;; Version: 0.1.0
+;; Version: 0.2.0
 ;; Author: Mozilla
-;; Package-Requires: ((cm-mode "0.1.0"))
 ;; Url: https://github.com/mozilla/rust
 
-(require 'cm-mode)
-(require 'cc-mode)
 (eval-when-compile (require 'cl))
 
-(defun rust-electric-brace (arg)
-  (interactive "*P")
-  (self-insert-command (prefix-numeric-value arg))
-  (when (and c-electric-flag
-             (not (member (get-text-property (point) 'face)
-                          '(font-lock-comment-face font-lock-string-face))))
-    (cm-indent)))
-
-(defcustom rust-capitalized-idents-are-types t
-  "If non-nil, capitalized identifiers will be treated as types for the purposes of font-lock mode"
-  :type 'boolean
-  :require 'rust-mode
-  :group 'rust-mode)
-
-(defcustom rust-indent-unit 4
-  "Amount of offset per level of indentation"
-  :type 'integer
-  :require 'rust-mode
-  :group 'rust-mode)
-
-(defvar rust-syntax-table (let ((table (make-syntax-table)))
-                            (c-populate-syntax-table table)
-                            table))
-
-(defun make-rust-state ()
-  (vector 'rust-token-base
-          (list (vector 'top (- rust-indent-unit) nil nil nil))
-          0
-          nil))
-(defmacro rust-state-tokenize (x) `(aref ,x 0))
-(defmacro rust-state-context (x) `(aref ,x 1))
-(defmacro rust-state-indent (x) `(aref ,x 2))
-(defmacro rust-state-last-token (x) `(aref ,x 3))
-
-(defmacro rust-context-type (x) `(aref ,x 0))
-(defmacro rust-context-indent (x) `(aref ,x 1))
-(defmacro rust-context-column (x) `(aref ,x 2))
-(defmacro rust-context-align (x) `(aref ,x 3))
-(defmacro rust-context-info (x) `(aref ,x 4))
-
-(defun rust-push-context (st type &optional align-column auto-align)
-  (let ((ctx (vector type (rust-state-indent st) align-column
-                     (if align-column (if auto-align t 'unset) nil) nil)))
-    (push ctx (rust-state-context st))
-    ctx))
-(defun rust-pop-context (st)
-  (let ((old (pop (rust-state-context st))))
-    (setf (rust-state-indent st) (rust-context-indent old))
-    old))
-(defun rust-dup-context (st)
-  (let* ((list (rust-state-context st))
-         (dup (copy-sequence (car list))))
-    (setf (rust-state-context st) (cons dup (cdr list)))
-    dup))
-
-(defvar rust-operator-chars "-+/%=<>!*&|@~^")
-(defvar rust-punc-chars "()[].,{}:;")
-(defvar rust-value-keywords
-  (let ((table (make-hash-table :test 'equal)))
-    (dolist (word '("mod" "const" "class" "type"
-                    "trait" "struct" "fn" "enum"
-                    "impl"))
-      (puthash word 'def table))
-    (dolist (word '("as" "break"
-                    "copy" "do" "drop" "else"
-                    "extern" "for" "if" "let" "log"
-                    "loop" "once" "priv" "pub" "pure"
-                    "ref" "return" "static" "unsafe" "use"
-                    "while" "while"
-                    "assert"
-                    "mut"))
-      (puthash word t table))
-    (puthash "match" 'alt table)
-    (dolist (word '("self" "true" "false")) (puthash word 'atom table))
+;; Syntax definitions and helpers
+(defvar rust-mode-syntax-table
+  (let ((table (make-syntax-table)))
+
+    ;; Operators
+    (loop for i in '(?+ ?- ?* ?/ ?& ?| ?^ ?! ?< ?> ?~ ?@)
+          do (modify-syntax-entry i "." table))
+
+    ;; Strings
+    (modify-syntax-entry ?\" "\"" table)
+    (modify-syntax-entry ?\\ "\\" table)
+
+    ;; _ is a word-char
+    (modify-syntax-entry ?_ "w" table)
+
+    ;; Comments
+    (modify-syntax-entry ?/  ". 124b" table)
+    (modify-syntax-entry ?*  ". 23"   table)
+    (modify-syntax-entry ?\n "> b"    table)
+    (modify-syntax-entry ?\^m "> b"   table)
+
     table))
-;; FIXME type-context keywords
-
-(defvar rust-tcat nil "Kludge for multiple returns without consing")
-
-(defmacro rust-eat-re (re)
-  `(when (looking-at ,re) (goto-char (match-end 0)) t))
-
-(defvar rust-char-table
-  (let ((table (make-char-table 'syntax-table)))
-    (macrolet ((def (range &rest body)
-                    `(let ((--b (lambda (st) ,@body)))
-                       ,@(mapcar (lambda (elt)
-	                           (if (consp elt)
-                                       `(loop for ch from ,(car elt) to ,(cdr elt) collect
-                                              (set-char-table-range table ch --b))
-                                     `(set-char-table-range table ',elt --b)))
-                                 (if (consp range) range (list range))))))
-      (def t (forward-char) nil)
-      (def (32 ?\t) (skip-chars-forward " \t") nil)
-      (def ?\" (forward-char)
-           (rust-push-context st 'string (current-column) t)
-           (setf (rust-state-tokenize st) 'rust-token-string)
-           (rust-token-string st))
-      (def ?\' (rust-single-quote))
-      (def ?/ (forward-char)
-           (case (char-after)
-             (?/ (end-of-line) 'font-lock-comment-face)
-             (?* (forward-char)
-                 (rust-push-context st 'comment)
-                 (setf (rust-state-tokenize st) 'rust-token-comment)
-                 (rust-token-comment st))
-             (t (skip-chars-forward rust-operator-chars) (setf rust-tcat 'op) nil)))
-      (def ?# (forward-char)
-           (cond ((eq (char-after) ?\[) (forward-char) (setf rust-tcat 'open-attr))
-                 ((rust-eat-re "[a-z_]+") (setf rust-tcat 'macro)))
-           'font-lock-preprocessor-face)
-      (def ((?a . ?z) (?A . ?Z) ?_)
-           (rust-token-identifier))
-      (def ((?0 . ?9))
-           (rust-eat-re "0x[0-9a-fA-F_]+\\|0b[01_]+\\|[0-9_]+\\(\\.[0-9_]+\\)?\\(e[+\\-]?[0-9_]+\\)?")
-           (setf rust-tcat 'atom)
-           (rust-eat-re "[iuf][0-9_]*")
-           'font-lock-constant-face)
-      (def ?. (forward-char)
-           (cond ((rust-eat-re "[0-9]+\\(e[+\\-]?[0-9]+\\)?")
-                  (setf rust-tcat 'atom)
-                  (rust-eat-re "f[0-9]+")
-                  'font-lock-constant-face)
-                 (t (setf rust-tcat (char-before)) nil)))
-      (def (?\( ?\) ?\[ ?\] ?\{ ?\} ?: ?\; ?,)
-           (forward-char)
-           (setf rust-tcat (char-before)) nil)
-      (def ?|
-           (skip-chars-forward rust-operator-chars)
-           (setf rust-tcat 'pipe) nil)
-      (def (?+ ?- ?% ?= ?< ?> ?! ?* ?& ?@ ?~)
-           (skip-chars-forward rust-operator-chars)
-           (setf rust-tcat 'op) nil)
-      table)))
-
-(defun rust-token-identifier ()
-  (rust-eat-re "[a-zA-Z_][a-zA-Z0-9_]*")
-  (setf rust-tcat 'ident)
-  (if (and (eq (char-after) ?:) (eq (char-after (+ (point) 1)) ?:)
-           (not (eq (char-after (+ (point) 2)) ?:)))
-      (progn (forward-char 2) 'font-lock-builtin-face)
-    (match-string 0)))
-
-(defun rust-single-quote ()
-  (forward-char)
-  (setf rust-tcat 'atom)
-  ; Is this a lifetime?
-  (if (or (looking-at "[a-zA-Z_]$")
-          (looking-at "[a-zA-Z_][^']"))
-      ; If what we see is 'abc, use font-lock-builtin-face:
-      (progn (rust-eat-re "[a-zA-Z_][a-zA-Z_0-9]*")
-             'font-lock-builtin-face)
-    ; Otherwise, handle as a character constant:
-    (let ((is-escape (eq (char-after) ?\\))
-          (start (point)))
-      (if (not (rust-eat-until-unescaped ?\'))
-          'font-lock-warning-face
-        (if (or is-escape (= (point) (+ start 2)))
-            'font-lock-string-face 'font-lock-warning-face)))))
-
-(defun rust-token-base (st)
-  (funcall (char-table-range rust-char-table (char-after)) st))
-
-(defun rust-eat-until-unescaped (ch)
-  (let (escaped)
-    (loop
-     (let ((cur (char-after)))
-       (when (or (eq cur ?\n) (not cur)) (return nil))
-       (forward-char)
-       (when (and (eq cur ch) (not escaped)) (return t))
-       (setf escaped (and (not escaped) (eq cur ?\\)))))))
-
-(defun rust-token-string (st)
-  (setf rust-tcat 'atom)
-  (cond ((rust-eat-until-unescaped ?\")
-         (setf (rust-state-tokenize st) 'rust-token-base)
-         (rust-pop-context st))
-        (t (let ((align (eq (char-before) ?\\)))
-             (unless (eq align (rust-context-align (car (rust-state-context st))))
-               (setf (rust-context-align (rust-dup-context st)) align)))))
-  'font-lock-string-face)
-
-(defun rust-token-comment (st)
-  (let ((eol (point-at-eol)))
-    (loop
-     (unless (re-search-forward "\\(/\\*\\)\\|\\(\\*/\\)" eol t)
-       (goto-char eol)
-       (return))
-     (if (match-beginning 1)
-         (push (car (rust-state-context st)) (rust-state-context st))
-       (rust-pop-context st)
-       (unless (eq (rust-context-type (car (rust-state-context st))) 'comment)
-         (setf (rust-state-tokenize st) 'rust-token-base)
-         (return))))
-    'font-lock-comment-face))
-
-(defun rust-next-block-info (st)
-  (dolist (cx (rust-state-context st))
-    (when (eq (rust-context-type cx) ?\}) (return (rust-context-info cx)))))
-
-(defun rust-is-capitalized (string)
-  (let ((case-fold-search nil))
-    (string-match-p "[A-Z]" string)))
-
-(defun rust-token (st)
-  (let ((cx (car (rust-state-context st))))
-    (when (bolp)
-      (setf (rust-state-indent st) (current-indentation))
-      (when (eq (rust-context-align cx) 'unset)
-        (setf (rust-context-align cx) nil)))
-    (setf rust-tcat nil)
-    (let* ((tok (funcall (rust-state-tokenize st) st))
-           (tok-id (or tok rust-tcat))
-           (cur-cx (rust-context-type cx))
-           (cx-info (rust-context-info cx)))
-      (when (stringp tok)
-        (setf tok-id (gethash tok rust-value-keywords nil))
-        (setf tok (cond ((eq tok-id 'atom) 'font-lock-constant-face)
-                        (tok-id 'font-lock-keyword-face)
-                        ((equal (rust-state-last-token st) 'def) 'font-lock-function-name-face)
-                        ((and rust-capitalized-idents-are-types
-                              (rust-is-capitalized tok)) 'font-lock-type-face)
-                        (t nil))))
-      (when rust-tcat
-        (when (eq (rust-context-align cx) 'unset)
-          (setf (rust-context-align cx) t))
-        (when (eq cx-info 'alt-1)
-          (setf cx (rust-dup-context st))
-          (setf (rust-context-info cx) 'alt-2))
-        (when (and (eq rust-tcat 'pipe) (eq (rust-state-last-token st) ?{))
-          (setf cx (rust-dup-context st))
-          (setf (rust-context-info cx) 'block))
-        (case rust-tcat
-          ((?\; ?,) (when (eq cur-cx 'statement) (rust-pop-context st)))
-          (?\{
-           (when (and (eq cur-cx 'statement) (not (member cx-info '(alt-1 alt-2))))
-             (rust-pop-context st))
-           (when (eq cx-info 'alt-2)
-             (setf cx (rust-dup-context st))
-             (setf (rust-context-info cx) nil))
-           (let ((next-info (rust-next-block-info st))
-                 (newcx (rust-push-context st ?\} (current-column))))
-             (cond ((eq cx-info 'alt-2) (setf (rust-context-info newcx) 'alt-outer))
-                   ((eq next-info 'alt-outer) (setf (rust-context-info newcx) 'alt-inner)))))
-          ((?\[ open-attr)
-           (let ((newcx (rust-push-context st ?\] (current-column))))
-             (when (eq rust-tcat 'open-attr)
-               (setf (rust-context-info newcx) 'attr))))
-          (?\( (rust-push-context st ?\) (current-column))
-               (when (eq (rust-context-info cx) 'attr)
-                 (setf (rust-context-info (car (rust-state-context st))) 'attr)))
-          (?\} (when (eq cur-cx 'statement) (rust-pop-context st))
-               (when (eq (rust-context-type (car (rust-state-context st))) ?})
-                 (rust-pop-context st))
-               (setf cx (car (rust-state-context st)))
-               (when (and (eq (rust-context-type cx) 'statement)
-                          (not (eq (rust-context-info cx) 'alt-2)))
-                 (rust-pop-context st)))
-          (t (cond ((eq cur-cx rust-tcat)
-                    (when (eq (rust-context-info (rust-pop-context st)) 'attr)
-                      (setf tok 'font-lock-preprocessor-face)
-                      (when (eq (rust-context-type (car (rust-state-context st))) 'statement)
-                        (rust-pop-context st))))
-                   ((or (and (eq cur-cx ?\}) (not (eq (rust-context-info cx) 'alt-outer)))
-                        (eq cur-cx 'top))
-                    (rust-push-context st 'statement)))))
-        (setf (rust-state-last-token st) tok-id))
-      (setf cx (car (rust-state-context st)))
-      (when (and (eq tok-id 'alt) (eq (rust-context-type cx) 'statement))
-        (setf (rust-context-info cx) 'alt-1))
-      (when (and (eq (rust-state-last-token st) 'pipe)
-                 (eq (rust-next-block-info st) 'block) (eolp))
-        (when (eq (rust-context-type cx) 'statement) (rust-pop-context st))
-        (setf cx (rust-dup-context st)
-              (rust-context-info cx) nil
-              (rust-context-align cx) nil))
-      (if (eq (rust-context-info cx) 'attr)
-          'font-lock-preprocessor-face
-        tok))))
-
-(defun rust-indent (st)
-  (let ((cx (car (rust-state-context st)))
-        (parent (cadr (rust-state-context st))))
-    (when (and (eq (rust-context-type cx) 'statement)
-               (or (eq (char-after) ?\}) (looking-at "with \\|{[ 	]*$")))
-      (setf cx parent parent (caddr (rust-state-context st))))
-    (let* ((tp (rust-context-type cx))
-           (closing (eq tp (char-after)))
-           (unit rust-indent-unit)
-           (base (if (and (eq tp 'statement) parent (rust-context-align parent))
-                     (rust-context-column parent) (rust-context-indent cx))))
-      (cond ((eq tp 'comment) base)
-            ((eq tp 'string) (if (rust-context-align cx) (rust-context-column cx) 0))
-            ((eq tp 'statement) (+ base (if (eq (char-after) ?\}) 0 unit)))
-            ((eq (rust-context-align cx) t) (+ (rust-context-column cx) (if closing -1 0)))
-            (t (+ base (if closing 0 unit)))))))
+
+(defun rust-paren-level () (nth 0 (syntax-ppss)))
+(defun rust-in-str-or-cmnt () (nth 8 (syntax-ppss)))
+(defun rust-rewind-past-str-cmnt () (goto-char (nth 8 (syntax-ppss))))
+(defun rust-rewind-irrelevant ()
+  (let ((starting (point)))
+    (skip-chars-backward "[:space:]\n")
+    (if (looking-back "\\*/") (backward-char))
+    (if (rust-in-str-or-cmnt)
+        (rust-rewind-past-str-cmnt))
+    (if (/= starting (point))
+        (rust-rewind-irrelevant))))
+
+(defun rust-mode-indent-line ()
+  (interactive)
+  (let ((indent
+         (save-excursion
+           (back-to-indentation)
+           (let ((level (rust-paren-level)))
+             (cond
+              ;; A function return type is 1 level indented
+              ((looking-at "->") (* default-tab-width (+ level 1)))
+
+              ;; A closing brace is 1 level unindended
+              ((looking-at "}") (* default-tab-width (- level 1)))
+
+              ;; If we're in any other token-tree / sexp, then:
+              ;;  - [ or ( means line up with the opening token
+              ;;  - { means indent to either nesting-level * tab width,
+              ;;    or one further indent from that if either current line
+              ;;    begins with 'else', or previous line didn't end in
+              ;;    semi, comma or brace, and wasn't an attribute. PHEW.
+              ((> level 0)
+               (let ((pt (point)))
+                 (rust-rewind-irrelevant)
+                 (backward-up-list)
+                 (if (looking-at "[[(]")
+                     (+ 1 (current-column))
+                   (progn
+                     (goto-char pt)
+                     (back-to-indentation)
+                     (if (looking-at "\\<else\\>")
+                         (* default-tab-width (+ 1 level))
+                       (progn
+                         (goto-char pt)
+                         (beginning-of-line)
+                         (rust-rewind-irrelevant)
+                         (end-of-line)
+                         (if (looking-back "[{};,]")
+                             (* default-tab-width level)
+                           (back-to-indentation)
+                           (if (looking-at "#")
+                               (* default-tab-width level)
+                             (* default-tab-width (+ 1 level))))))))))
+
+              ;; Otherwise we're in a column-zero definition
+              (t 0))))))
+    (cond
+     ;; If we're to the left of the indentation, reindent and jump to it.
+     ((<= (current-column) indent)
+      (indent-line-to indent))
+
+     ;; We're to the right; if it needs indent, do so but save excursion.
+     ((not (eq (current-indentation) indent))
+      (save-excursion (indent-line-to indent))))))
+
+
+;; Font-locking definitions and helpers
+(defconst rust-mode-keywords
+  '("as"
+    "break"
+    "do"
+    "else" "enum" "extern"
+    "false" "fn" "for"
+    "if" "impl"
+    "let" "loop"
+    "match" "mod" "mut"
+    "priv" "pub"
+    "ref" "return"
+    "self" "static" "struct" "super"
+    "true" "trait" "type"
+    "unsafe" "use"
+    "while"))
+
+(defconst rust-special-types
+  '("u8" "i8"
+    "u16" "i16"
+    "u32" "i32"
+    "u64" "i64"
+
+    "f32" "f64"
+    "float" "int" "uint"
+    "bool"
+    "str" "char"))
+
+(defconst rust-re-ident "[[:word:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
+(defconst rust-re-CamelCase "[[:upper:]][[:word:][:multibyte:]_[:digit:]]*")
+(defun rust-re-word (inner) (concat "\\<" inner "\\>"))
+(defun rust-re-grab (inner) (concat "\\(" inner "\\)"))
+(defun rust-re-grabword (inner) (rust-re-grab (rust-re-word inner)))
+(defun rust-re-item-def (itype)
+  (concat (rust-re-word itype) "[[:space:]]+" (rust-re-grab rust-re-ident)))
+
+(defvar rust-mode-font-lock-keywords
+  (append
+   `(
+     ;; Keywords proper
+     (,(regexp-opt rust-mode-keywords 'words) . font-lock-keyword-face)
+
+     ;; Special types
+     (,(regexp-opt rust-special-types 'words) . font-lock-type-face)
+
+     ;; Attributes like `#[bar(baz)]`
+     (,(rust-re-grab (concat "#\\[" rust-re-ident "[^]]*\\]"))
+      1 font-lock-preprocessor-face)
+
+     ;; Syntax extension invocations like `foo!`, highlight including the !
+     (,(concat (rust-re-grab (concat rust-re-ident "!")) "[({[:space:]]")
+      1 font-lock-preprocessor-face)
+
+     ;; Field names like `foo:`, highlight excluding the :
+     (,(concat (rust-re-grab rust-re-ident) ":[^:]") 1 font-lock-variable-name-face)
+
+     ;; Module names like `foo::`, highlight including the ::
+     (,(rust-re-grab (concat rust-re-ident "::")) 1 font-lock-type-face)
+
+     ;; Lifetimes like `'foo`
+     (,(concat "'" (rust-re-grab rust-re-ident) "[^']") 1 font-lock-variable-name-face)
+
+     ;; Character constants, since they're not treated as strings
+     ;; in order to have sufficient leeway to parse 'lifetime above.
+     (,(rust-re-grab "'[^']'") 1 font-lock-string-face)
+     (,(rust-re-grab "'\\\\[nrt]'") 1 font-lock-string-face)
+     (,(rust-re-grab "'\\\\x[[:xdigit:]]\\{2\\}'") 1 font-lock-string-face)
+     (,(rust-re-grab "'\\\\u[[:xdigit:]]\\{4\\}'") 1 font-lock-string-face)
+     (,(rust-re-grab "'\\\\U[[:xdigit:]]\\{8\\}'") 1 font-lock-string-face)
+
+     ;; CamelCase Means Type Or Constructor
+     (,(rust-re-grabword rust-re-CamelCase) 1 font-lock-type-face)
+     )
+
+   ;; Item definitions
+   (loop for (item . face) in
+
+         '(("enum" . font-lock-type-face)
+           ("struct" . font-lock-type-face)
+           ("type" . font-lock-type-face)
+           ("mod" . font-lock-type-face)
+           ("use" . font-lock-type-face)
+           ("fn" . font-lock-function-name-face)
+           ("static" . font-lock-constant-face))
+
+         collect `(,(rust-re-item-def item) 1 ,face))))
+
+
+;; For compatibility with Emacs < 24, derive conditionally
+(defalias 'rust-parent-mode
+  (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
+
 
 ;;;###autoload
-(define-derived-mode rust-mode fundamental-mode "Rust"
-  "Major mode for editing Rust source files."
-  (set-syntax-table rust-syntax-table)
-  (setq major-mode 'rust-mode mode-name "Rust")
-  (run-hooks 'rust-mode-hook)
-  (set (make-local-variable 'indent-tabs-mode) nil)
-  (let ((par "[ 	]*\\(//+\\|\\**\\)[ 	]*$"))
-    (set (make-local-variable 'paragraph-start) par)
-    (set (make-local-variable 'paragraph-separate) par))
-  (set (make-local-variable 'comment-start) "//")
-  (cm-mode (make-cm-mode 'rust-token 'make-rust-state 'copy-sequence 'equal 'rust-indent)))
-
-(define-key rust-mode-map "}" 'rust-electric-brace)
-(define-key rust-mode-map "{" 'rust-electric-brace)
+(define-derived-mode rust-mode rust-parent-mode "Rust"
+  "Major mode for Rust code."
+
+  ;; Basic syntax
+  (set-syntax-table rust-mode-syntax-table)
+
+  ;; Indentation
+  (set (make-local-variable 'indent-line-function)
+       'rust-mode-indent-line)
+
+  ;; Fonts
+  (set (make-local-variable 'font-lock-defaults)
+       '(rust-mode-font-lock-keywords nil nil nil nil))
+
+  ;; Misc
+  (set (make-local-variable 'comment-start) "// ")
+  (set (make-local-variable 'comment-end)   "")
+  (set (make-local-variable 'indent-tabs-mode) nil))
+
 
 ;;;###autoload
-(progn
-  (add-to-list 'auto-mode-alist '("\\.rs$" . rust-mode))
-  (add-to-list 'auto-mode-alist '("\\.rc$" . rust-mode)))
+(add-to-list 'auto-mode-alist '("\\.rs$" . rust-mode))
+
+(defun rust-mode-reload ()
+  (interactive)
+  (unload-feature 'rust-mode)
+  (require 'rust-mode)
+  (rust-mode))
 
 (provide 'rust-mode)
 
diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs
index d940b6d6667..46a74457274 100644
--- a/src/libextra/num/bigint.rs
+++ b/src/libextra/num/bigint.rs
@@ -732,6 +732,11 @@ impl Ord for Sign {
     }
 }
 
+impl TotalEq for Sign {
+    fn equals(&self, other: &Sign) -> bool {
+        *self == *other
+    }
+}
 impl TotalOrd for Sign {
 
     fn cmp(&self, other: &Sign) -> Ordering {
diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs
index 6733599d1ea..ff14009e556 100644
--- a/src/libextra/num/rational.rs
+++ b/src/libextra/num/rational.rs
@@ -110,6 +110,25 @@ cmp_impl!(impl TotalEq, equals)
 cmp_impl!(impl Ord, lt, gt, le, ge)
 cmp_impl!(impl TotalOrd, cmp -> cmp::Ordering)
 
+impl<T: Clone + Integer + Ord> Orderable for Ratio<T> {
+    #[inline]
+    fn min(&self, other: &Ratio<T>) -> Ratio<T> {
+        if *self < *other { self.clone() } else { other.clone() }
+    }
+
+    #[inline]
+    fn max(&self, other: &Ratio<T>) -> Ratio<T> {
+        if *self > *other { self.clone() } else { other.clone() }
+    }
+
+    #[inline]
+    fn clamp(&self, mn: &Ratio<T>, mx: &Ratio<T>) -> Ratio<T> {
+        if *self > *mx { mx.clone()} else
+        if *self < *mn { mn.clone() } else { self.clone() }
+    }
+}
+
+
 /* Arithmetic */
 // a/b * c/d = (a*c)/(b*d)
 impl<T: Clone + Integer + Ord>
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index 645188ce5a4..1c5d202d4d9 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -180,6 +180,7 @@ pub static tag_misc_info: uint = 0x7f;
 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 struct LinkMeta {
     name: @str,
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 97344ee91ad..6f7feae4479 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -16,6 +16,7 @@ use metadata::cstore;
 use metadata::decoder;
 use metadata;
 use middle::ty;
+use middle::typeck;
 
 use std::vec;
 use reader = extra::ebml::reader;
@@ -216,6 +217,14 @@ pub fn get_impl_trait(tcx: ty::ctxt,
     decoder::get_impl_trait(cdata, def.node, tcx)
 }
 
+// Given a def_id for an impl, return information about its vtables
+pub fn get_impl_vtables(tcx: ty::ctxt,
+                        def: ast::def_id) -> typeck::impl_res {
+    let cstore = tcx.cstore;
+    let cdata = cstore::get_crate_data(cstore, def.crate);
+    decoder::get_impl_vtables(cdata, def.node, tcx)
+}
+
 pub fn get_impl_method(cstore: @mut cstore::CStore,
                        def: ast::def_id,
                        mname: ast::ident)
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 6e166cfbfc8..01c5019154f 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -21,9 +21,12 @@ 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;
+use middle::typeck;
+use middle::astencode::vtable_decoder_helpers;
+
 
 use std::hash::HashUtil;
-use std::int;
+use std::uint;
 use std::io::WriterUtil;
 use std::io;
 use std::option;
@@ -200,9 +203,9 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
     return true;
 }
 
-fn variant_disr_val(d: ebml::Doc) -> Option<int> {
+fn variant_disr_val(d: ebml::Doc) -> Option<uint> {
     do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
-        do reader::with_doc_data(val_doc) |data| { int::parse_bytes(data, 10u) }
+        do reader::with_doc_data(val_doc) |data| { uint::parse_bytes(data, 10u) }
     }
 }
 
@@ -410,6 +413,21 @@ pub fn get_impl_trait(cdata: cmd,
     }
 }
 
+pub fn get_impl_vtables(cdata: cmd,
+                        id: ast::node_id,
+                        tcx: ty::ctxt) -> typeck::impl_res
+{
+    let item_doc = lookup_item(id, cdata.data);
+    let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables);
+    let mut decoder = reader::Decoder(vtables_doc);
+
+    typeck::impl_res {
+        trait_vtables: decoder.read_vtable_res(tcx, cdata),
+        self_vtables: decoder.read_vtable_param_res(tcx, cdata)
+    }
+}
+
+
 pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
                        name: ast::ident) -> Option<ast::def_id> {
     let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 78e1a579d74..d6287d457c1 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -17,11 +17,12 @@ use metadata::decoder;
 use metadata::tyencode;
 use middle::ty::{node_id_to_type, lookup_item_type};
 use middle::ty;
+use middle::typeck;
+use middle::astencode;
 use middle;
 
 use std::hash::HashUtil;
 use std::hashmap::{HashMap, HashSet};
-use std::int;
 use std::io;
 use std::str;
 use std::uint;
@@ -162,6 +163,15 @@ fn encode_trait_ref(ebml_w: &mut writer::Encoder,
     ebml_w.end_tag();
 }
 
+fn encode_impl_vtables(ebml_w: &mut writer::Encoder,
+                       ecx: &EncodeContext,
+                       vtables: &typeck::impl_res) {
+    ebml_w.start_tag(tag_item_impl_vtables);
+    astencode::encode_vtable_res(ecx, ebml_w, vtables.trait_vtables);
+    astencode::encode_vtable_param_res(ecx, ebml_w, vtables.self_vtables);
+    ebml_w.end_tag();
+}
+
 // Item info table encoding
 fn encode_family(ebml_w: &mut writer::Encoder, c: char) {
     ebml_w.start_tag(tag_items_data_item_family);
@@ -290,9 +300,9 @@ fn encode_discriminant(ecx: &EncodeContext,
 
 fn encode_disr_val(_: &EncodeContext,
                    ebml_w: &mut writer::Encoder,
-                   disr_val: int) {
+                   disr_val: uint) {
     ebml_w.start_tag(tag_disr_val);
-    let s = int::to_str(disr_val);
+    let s = uint::to_str(disr_val);
     ebml_w.writer.write(s.as_bytes());
     ebml_w.end_tag();
 }
@@ -1009,6 +1019,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
             let trait_ref = ty::node_id_to_trait_ref(
                 tcx, ast_trait_ref.ref_id);
             encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
+            let impl_vtables = ty::lookup_impl_vtables(tcx, def_id);
+            encode_impl_vtables(ebml_w, ecx, &impl_vtables);
         }
         encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
         ebml_w.end_tag();
@@ -1443,6 +1455,9 @@ fn encode_lang_items(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
     ebml_w.start_tag(tag_lang_items);
 
     for ecx.tcx.lang_items.each_item |def_id, i| {
+        let def_id = match def_id {
+            Some(id) => id, None => { loop }
+        };
         if def_id.crate != local_crate {
             loop;
         }
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 1edd3c805d0..89b30e46ac0 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -186,7 +186,7 @@ fn parse_trait_store(st: &mut PState) -> ty::TraitStore {
 }
 
 fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs {
-    let self_r = parse_opt(st, |st| parse_region(st) );
+    let regions = parse_region_substs(st);
 
     let self_ty = parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)) );
 
@@ -196,12 +196,28 @@ fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs {
     st.pos = st.pos + 1u;
 
     return ty::substs {
-        self_r: self_r,
+        regions: regions,
         self_ty: self_ty,
         tps: params
     };
 }
 
+fn parse_region_substs(st: &mut PState) -> ty::RegionSubsts {
+    match next(st) {
+        'e' => ty::ErasedRegions,
+        'n' => {
+            let mut regions = opt_vec::Empty;
+            while peek(st) != '.' {
+                let r = parse_region(st);
+                regions.push(r);
+            }
+            assert_eq!(next(st), '.');
+            ty::NonerasedRegions(regions)
+        }
+        _ => fail!("parse_bound_region: bad input")
+    }
+}
+
 fn parse_bound_region(st: &mut PState) -> ty::bound_region {
     match next(st) {
       's' => ty::br_self,
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index bab13c2b470..a1cb1bf6848 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -120,13 +120,28 @@ fn enc_opt<T>(w: @io::Writer, t: Option<T>, enc_f: &fn(T)) {
 }
 
 fn enc_substs(w: @io::Writer, cx: @ctxt, substs: &ty::substs) {
-    do enc_opt(w, substs.self_r) |r| { enc_region(w, cx, r) }
+    enc_region_substs(w, cx, &substs.regions);
     do enc_opt(w, substs.self_ty) |t| { enc_ty(w, cx, t) }
     w.write_char('[');
     for substs.tps.iter().advance |t| { enc_ty(w, cx, *t); }
     w.write_char(']');
 }
 
+fn enc_region_substs(w: @io::Writer, cx: @ctxt, substs: &ty::RegionSubsts) {
+    match *substs {
+        ty::ErasedRegions => {
+            w.write_char('e');
+        }
+        ty::NonerasedRegions(ref regions) => {
+            w.write_char('n');
+            for regions.iter().advance |&r| {
+                enc_region(w, cx, r);
+            }
+            w.write_char('.');
+        }
+    }
+}
+
 fn enc_region(w: @io::Writer, cx: @ctxt, r: ty::Region) {
     match r {
       ty::re_bound(br) => {
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index f3e0779475c..bf39be407c5 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -250,6 +250,8 @@ impl<S:serialize::Encoder> def_id_encoder_helpers for S {
 
 trait def_id_decoder_helpers {
     fn read_def_id(&mut self, xcx: @ExtendedDecodeContext) -> ast::def_id;
+    fn read_def_id_noxcx(&mut self,
+                         cdata: @cstore::crate_metadata) -> ast::def_id;
 }
 
 impl<D:serialize::Decoder> def_id_decoder_helpers for D {
@@ -257,6 +259,12 @@ impl<D:serialize::Decoder> def_id_decoder_helpers for D {
         let did: ast::def_id = Decodable::decode(self);
         did.tr(xcx)
     }
+
+    fn read_def_id_noxcx(&mut self,
+                         cdata: @cstore::crate_metadata) -> ast::def_id {
+        let did: ast::def_id = Decodable::decode(self);
+        decoder::translate_def_id(cdata, did)
+    }
 }
 
 // ______________________________________________________________________
@@ -582,12 +590,6 @@ impl tr for method_origin {
           typeck::method_trait(did, m, vstore) => {
               typeck::method_trait(did.tr(xcx), m, vstore)
           }
-          typeck::method_self(did, m) => {
-              typeck::method_self(did.tr(xcx), m)
-          }
-          typeck::method_super(trait_did, m) => {
-              typeck::method_super(trait_did.tr(xcx), m)
-          }
         }
     }
 }
@@ -595,7 +597,7 @@ impl tr for method_origin {
 // ______________________________________________________________________
 // Encoding and decoding vtable_res
 
-fn encode_vtable_res(ecx: &e::EncodeContext,
+pub fn encode_vtable_res(ecx: &e::EncodeContext,
                      ebml_w: &mut writer::Encoder,
                      dr: typeck::vtable_res) {
     // can't autogenerate this code because automatic code of
@@ -603,13 +605,20 @@ fn encode_vtable_res(ecx: &e::EncodeContext,
     // hand-written encoding routines combine with auto-generated
     // ones.  perhaps we should fix this.
     do ebml_w.emit_from_vec(*dr) |ebml_w, param_tables| {
-        do ebml_w.emit_from_vec(**param_tables) |ebml_w, vtable_origin| {
-            encode_vtable_origin(ecx, ebml_w, vtable_origin)
-        }
+        encode_vtable_param_res(ecx, ebml_w, *param_tables);
     }
 }
 
-fn encode_vtable_origin(ecx: &e::EncodeContext,
+pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
+                     ebml_w: &mut writer::Encoder,
+                     param_tables: typeck::vtable_param_res) {
+    do ebml_w.emit_from_vec(*param_tables) |ebml_w, vtable_origin| {
+        encode_vtable_origin(ecx, ebml_w, vtable_origin)
+    }
+}
+
+
+pub fn encode_vtable_origin(ecx: &e::EncodeContext,
                         ebml_w: &mut writer::Encoder,
                         vtable_origin: &typeck::vtable_origin) {
     do ebml_w.emit_enum("vtable_origin") |ebml_w| {
@@ -630,40 +639,46 @@ fn encode_vtable_origin(ecx: &e::EncodeContext,
           typeck::vtable_param(pn, bn) => {
             do ebml_w.emit_enum_variant("vtable_param", 1u, 2u) |ebml_w| {
                 do ebml_w.emit_enum_variant_arg(0u) |ebml_w| {
-                    ebml_w.emit_uint(pn);
+                    pn.encode(ebml_w);
                 }
                 do ebml_w.emit_enum_variant_arg(1u) |ebml_w| {
                     ebml_w.emit_uint(bn);
                 }
             }
           }
-          typeck::vtable_self(def_id) => {
-            do ebml_w.emit_enum_variant("vtable_self", 2u, 1u) |ebml_w| {
-                do ebml_w.emit_enum_variant_arg(0u) |ebml_w| {
-                    ebml_w.emit_def_id(def_id)
-                }
-            }
-          }
         }
     }
 }
 
-trait vtable_decoder_helpers {
-    fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
+pub trait vtable_decoder_helpers {
+    fn read_vtable_res(&mut self,
+                       tcx: ty::ctxt, cdata: @cstore::crate_metadata)
                       -> typeck::vtable_res;
-    fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)
+    fn read_vtable_param_res(&mut self,
+                       tcx: ty::ctxt, cdata: @cstore::crate_metadata)
+                      -> typeck::vtable_param_res;
+    fn read_vtable_origin(&mut self,
+                          tcx: ty::ctxt, cdata: @cstore::crate_metadata)
                           -> typeck::vtable_origin;
 }
 
 impl vtable_decoder_helpers for reader::Decoder {
-    fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
+    fn read_vtable_res(&mut self,
+                       tcx: ty::ctxt, cdata: @cstore::crate_metadata)
                       -> typeck::vtable_res {
         @self.read_to_vec(|this|
-           @this.read_to_vec(|this|
-               this.read_vtable_origin(xcx)))
+                          this.read_vtable_param_res(tcx, cdata))
     }
 
-    fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)
+    fn read_vtable_param_res(&mut self,
+                             tcx: ty::ctxt, cdata: @cstore::crate_metadata)
+                      -> typeck::vtable_param_res {
+        @self.read_to_vec(|this|
+                          this.read_vtable_origin(tcx, cdata))
+    }
+
+    fn read_vtable_origin(&mut self,
+                          tcx: ty::ctxt, cdata: @cstore::crate_metadata)
         -> typeck::vtable_origin {
         do self.read_enum("vtable_origin") |this| {
             do this.read_enum_variant(["vtable_static",
@@ -674,33 +689,26 @@ impl vtable_decoder_helpers for reader::Decoder {
                   0 => {
                     typeck::vtable_static(
                         do this.read_enum_variant_arg(0u) |this| {
-                            this.read_def_id(xcx)
+                            this.read_def_id_noxcx(cdata)
                         },
                         do this.read_enum_variant_arg(1u) |this| {
-                            this.read_tys(xcx)
+                            this.read_tys_noxcx(tcx, cdata)
                         },
                         do this.read_enum_variant_arg(2u) |this| {
-                            this.read_vtable_res(xcx)
+                            this.read_vtable_res(tcx, cdata)
                         }
                     )
                   }
                   1 => {
                     typeck::vtable_param(
                         do this.read_enum_variant_arg(0u) |this| {
-                            this.read_uint()
+                            Decodable::decode(this)
                         },
                         do this.read_enum_variant_arg(1u) |this| {
                             this.read_uint()
                         }
                     )
                   }
-                  2 => {
-                    typeck::vtable_self(
-                        do this.read_enum_variant_arg(0u) |this| {
-                            this.read_def_id(xcx)
-                        }
-                    )
-                  }
                   // hard to avoid - user input
                   _ => fail!("bad enum variant")
                 }
@@ -995,9 +1003,35 @@ trait ebml_decoder_decoder_helpers {
                       source: DefIdSource,
                       did: ast::def_id)
                       -> ast::def_id;
+
+    // Versions of the type reading functions that don't need the full
+    // ExtendedDecodeContext.
+    fn read_ty_noxcx(&mut self,
+                     tcx: ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t;
+    fn read_tys_noxcx(&mut self,
+                      tcx: ty::ctxt,
+                      cdata: @cstore::crate_metadata) -> ~[ty::t];
 }
 
 impl ebml_decoder_decoder_helpers for reader::Decoder {
+    fn read_ty_noxcx(&mut self,
+                     tcx: ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t {
+        do self.read_opaque |_, doc| {
+            tydecode::parse_ty_data(
+                *doc.data,
+                cdata.cnum,
+                doc.start,
+                tcx,
+                |_, id| decoder::translate_def_id(cdata, id))
+        }
+    }
+
+    fn read_tys_noxcx(&mut self,
+                      tcx: ty::ctxt,
+                      cdata: @cstore::crate_metadata) -> ~[ty::t] {
+        self.read_to_vec(|this| this.read_ty_noxcx(tcx, cdata) )
+    }
+
     fn read_ty(&mut self, xcx: @ExtendedDecodeContext) -> ty::t {
         // Note: regions types embed local node ids.  In principle, we
         // should translate these node ids into the new decode
@@ -1160,8 +1194,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
                             val_dsr.read_method_map_entry(xcx));
                     }
                     c::tag_table_vtable_map => {
-                        dcx.maps.vtable_map.insert(id,
-                                                   val_dsr.read_vtable_res(xcx));
+                        dcx.maps.vtable_map.insert(
+                            id,
+                            val_dsr.read_vtable_res(xcx.dcx.tcx, xcx.dcx.cdata));
                     }
                     c::tag_table_adjustments => {
                         let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr);
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 36edb567a50..793cd374718 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -10,7 +10,7 @@
 
 
 use middle::const_eval::{compare_const_vals, lookup_const_by_id};
-use middle::const_eval::{eval_const_expr, const_val, const_bool};
+use middle::const_eval::{eval_const_expr, const_val, const_bool, const_float};
 use middle::pat_util::*;
 use middle::ty::*;
 use middle::ty;
@@ -102,6 +102,27 @@ pub fn check_arms(cx: &MatchCheckCtxt, arms: &[arm]) {
     let mut seen = ~[];
     for arms.iter().advance |arm| {
         for arm.pats.iter().advance |pat| {
+
+            // Check that we do not match against a static NaN (#6804)
+            let pat_matches_nan: &fn(@pat) -> bool = |p| {
+                match cx.tcx.def_map.find(&p.id) {
+                    Some(&def_static(did, false)) => {
+                        let const_expr = lookup_const_by_id(cx.tcx, did).get();
+                        match eval_const_expr(cx.tcx, const_expr) {
+                            const_float(f) if f.is_NaN() => true,
+                            _ => false
+                        }
+                    }
+                    _ => false
+                }
+            };
+            for walk_pat(*pat) |p| {
+                if pat_matches_nan(p) {
+                    cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \
+                                                   use the is_NaN method in a guard instead");
+                }
+            }
+
             let v = ~[*pat];
             match is_useful(cx, &seen, v) {
               not_useful => {
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index eb9d18c9b24..99aae34911b 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -19,6 +19,7 @@ use util::ppaux::UserString;
 use syntax::ast::*;
 use syntax::attr;
 use syntax::codemap::span;
+use syntax::opt_vec;
 use syntax::print::pprust::expr_to_str;
 use syntax::{visit, ast_util};
 
@@ -83,7 +84,7 @@ fn check_struct_safe_for_destructor(cx: Context,
     let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did);
     if !struct_tpt.generics.has_type_params() {
         let struct_ty = ty::mk_struct(cx.tcx, struct_did, ty::substs {
-            self_r: None,
+            regions: ty::NonerasedRegions(opt_vec::Empty),
             self_ty: None,
             tps: ~[]
         });
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 6bc4564bb13..54e7a2fd7e7 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -92,8 +92,8 @@ impl LanguageItems {
         }
     }
 
-    pub fn each_item(&self, f: &fn(def_id: def_id, i: uint) -> bool) -> bool {
-        self.items.iter().enumerate().advance(|(i, &item)| f(item.get(), i))
+    pub fn each_item(&self, f: &fn(Option<def_id>, uint) -> bool) -> bool {
+        self.items.iter().enumerate().advance(|(i, &item)| f(item, i))
     }
 
     pub fn item_name(index: uint) -> &'static str {
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 4bcb40a5fba..aaf0460a4e1 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -79,7 +79,6 @@ pub enum lint {
     non_camel_case_types,
     non_uppercase_statics,
     type_limits,
-    default_methods,
     unused_unsafe,
 
     managed_heap_memory,
@@ -222,13 +221,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
         default: warn
      }),
 
-    ("default_methods",
-     LintSpec {
-        lint: default_methods,
-        desc: "allow default methods",
-        default: allow
-     }),
-
     ("unused_unsafe",
      LintSpec {
         lint: unused_unsafe,
@@ -690,23 +682,6 @@ fn lint_type_limits() -> visit::vt<@mut Context> {
     })
 }
 
-fn check_item_default_methods(cx: &Context, item: &ast::item) {
-    match item.node {
-        ast::item_trait(_, _, ref methods) => {
-            for methods.iter().advance |method| {
-                match *method {
-                    ast::required(*) => {}
-                    ast::provided(*) => {
-                        cx.span_lint(default_methods, item.span,
-                                     "default methods are experimental");
-                    }
-                }
-            }
-        }
-        _ => {}
-    }
-}
-
 fn check_item_ctypes(cx: &Context, it: &ast::item) {
     fn check_ty(cx: &Context, ty: &ast::Ty) {
         match ty.node {
@@ -852,23 +827,26 @@ fn check_item_non_camel_case_types(cx: &Context, it: &ast::item) {
             !ident.contains_char('_')
     }
 
-    fn check_case(cx: &Context, ident: ast::ident, span: span) {
+    fn check_case(cx: &Context, sort: &str, ident: ast::ident, span: span) {
         if !is_camel_case(cx.tcx, ident) {
-            cx.span_lint(non_camel_case_types, span,
-                         "type, variant, or trait should have \
-                          a camel case identifier");
+            cx.span_lint(
+                non_camel_case_types, span,
+                fmt!("%s `%s` should have a camel case identifier",
+                    sort, cx.tcx.sess.str_of(ident)));
         }
     }
 
     match it.node {
-        ast::item_ty(*) | ast::item_struct(*) |
+        ast::item_ty(*) | ast::item_struct(*) => {
+            check_case(cx, "type", it.ident, it.span)
+        }
         ast::item_trait(*) => {
-            check_case(cx, it.ident, it.span)
+            check_case(cx, "trait", it.ident, it.span)
         }
         ast::item_enum(ref enum_definition, _) => {
-            check_case(cx, it.ident, it.span);
+            check_case(cx, "type", it.ident, it.span);
             for enum_definition.variants.iter().advance |variant| {
-                check_case(cx, variant.node.name, variant.span);
+                check_case(cx, "variant", variant.node.name, variant.span);
             }
         }
         _ => ()
@@ -1143,7 +1121,6 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::Crate) {
                     check_item_ctypes(cx, it);
                     check_item_non_camel_case_types(cx, it);
                     check_item_non_uppercase_statics(cx, it);
-                    check_item_default_methods(cx, it);
                     check_item_heap(cx, it);
 
                     cx.process(Item(it));
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 1ea32b3f404..e768a6d687c 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -15,8 +15,7 @@
 use metadata::csearch;
 use middle::ty::{ty_struct, ty_enum};
 use middle::ty;
-use middle::typeck::{method_map, method_origin, method_param, method_self};
-use middle::typeck::{method_super};
+use middle::typeck::{method_map, method_origin, method_param};
 use middle::typeck::{method_static, method_trait};
 
 use std::util::ignore;
@@ -291,9 +290,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
                  method_num: method_num,
                  _
             }) |
-            method_trait(trait_id, method_num, _) |
-            method_self(trait_id, method_num) |
-            method_super(trait_id, method_num) => {
+            method_trait(trait_id, method_num, _) => {
                 if trait_id.crate == local_crate {
                     match tcx.items.find(&trait_id.node) {
                         Some(&node_item(item, _)) => {
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index d43cea2c733..7b2b130bc68 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -12,6 +12,7 @@
 
 
 use middle::ty;
+use syntax::opt_vec::OptVec;
 use util::ppaux::Repr;
 
 ///////////////////////////////////////////////////////////////////////////
@@ -79,6 +80,12 @@ impl<T:Subst> Subst for ~[T] {
     }
 }
 
+impl<T:Subst> Subst for OptVec<T> {
+    fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> OptVec<T> {
+        self.map(|t| t.subst(tcx, substs))
+    }
+}
+
 impl<T:Subst + 'static> Subst for @T {
     fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> @T {
         match self {
@@ -105,13 +112,26 @@ impl Subst for ty::TraitRef {
 impl Subst for ty::substs {
     fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::substs {
         ty::substs {
-            self_r: self.self_r.subst(tcx, substs),
+            regions: self.regions.subst(tcx, substs),
             self_ty: self.self_ty.map(|typ| typ.subst(tcx, substs)),
             tps: self.tps.map(|typ| typ.subst(tcx, substs))
         }
     }
 }
 
+impl Subst for ty::RegionSubsts {
+    fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::RegionSubsts {
+        match *self {
+            ty::ErasedRegions => {
+                ty::ErasedRegions
+            }
+            ty::NonerasedRegions(ref regions) => {
+                ty::NonerasedRegions(regions.subst(tcx, substs))
+            }
+        }
+    }
+}
+
 impl Subst for ty::BareFnTy {
     fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::BareFnTy {
         ty::fold_bare_fn_ty(self, |t| t.subst(tcx, substs))
@@ -158,15 +178,18 @@ impl Subst for ty::Region {
         // will most likely disappear.
         match self {
             &ty::re_bound(ty::br_self) => {
-                match substs.self_r {
-                    None => {
-                        tcx.sess.bug(
-                            fmt!("ty::Region#subst(): \
-                                  Reference to self region when \
-                                  given substs with no self region: %s",
-                                 substs.repr(tcx)));
+                match substs.regions {
+                    ty::ErasedRegions => ty::re_static,
+                    ty::NonerasedRegions(ref regions) => {
+                        if regions.len() != 1 {
+                            tcx.sess.bug(
+                                fmt!("ty::Region#subst(): \
+                                      Reference to self region when \
+                                      given substs with no self region: %s",
+                                     substs.repr(tcx)));
+                        }
+                        *regions.get(0)
                     }
-                    Some(self_r) => self_r
                 }
             }
             _ => *self
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 843aa2b749c..648dd033287 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -193,7 +193,7 @@ pub enum Lit {
 // range)
 pub enum Opt {
     lit(Lit),
-    var(/* disr val */int, @adt::Repr),
+    var(/* disr val */ uint, @adt::Repr),
     range(@ast::expr, @ast::expr),
     vec_len_eq(uint),
     vec_len_ge(uint, /* slice */uint)
@@ -874,7 +874,7 @@ pub struct ExtractedBlock {
 
 pub fn extract_variant_args(bcx: @mut Block,
                             repr: &adt::Repr,
-                            disr_val: int,
+                            disr_val: uint,
                             val: ValueRef)
     -> ExtractedBlock {
     let _icx = push_ctxt("match::extract_variant_args");
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index ee53bfdcbda..4a541c17a23 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -64,7 +64,7 @@ use middle::trans::type_::Type;
 /// Representations.
 pub enum Repr {
     /// C-like enums; basically an int.
-    CEnum(int, int), // discriminant range
+    CEnum(uint, uint), // discriminant range
     /**
      * Single-case variants, and structs/tuples/records.
      *
@@ -89,7 +89,7 @@ pub enum Repr {
      * is represented such that `None` is a null pointer and `Some` is the
      * identity function.
      */
-    NullablePointer{ nonnull: Struct, nndiscr: int, ptrfield: uint,
+    NullablePointer{ nonnull: Struct, nndiscr: uint, ptrfield: uint,
                      nullfields: ~[ty::t] }
 }
 
@@ -140,7 +140,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             return Univariant(mk_struct(cx, ftys, packed), dtor)
         }
         ty::ty_enum(def_id, ref substs) => {
-            struct Case { discr: int, tys: ~[ty::t] };
+            struct Case { discr: uint, tys: ~[ty::t] };
             impl Case {
                 fn is_zerolen(&self, cx: &mut CrateContext) -> bool {
                     mk_struct(cx, self.tys, false).size == 0
@@ -177,7 +177,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             // Since there's at least one
             // non-empty body, explicit discriminants should have
             // been rejected by a checker before this point.
-            if !cases.iter().enumerate().all(|(i,c)| c.discr == (i as int)) {
+            if !cases.iter().enumerate().all(|(i,c)| c.discr == i) {
                 cx.sess.bug(fmt!("non-C-like enum %s with specified \
                                   discriminants",
                                  ty::item_path_str(cx.tcx, def_id)))
@@ -206,7 +206,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {
             }
 
             // The general case.
-            let discr = ~[ty::mk_int()];
+            let discr = ~[ty::mk_uint()];
             return General(cases.map(|c| mk_struct(cx, discr + c.tys, false)))
         }
         _ => cx.sess.bug("adt::represent_type called on non-ADT type")
@@ -305,9 +305,8 @@ pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
     -> ValueRef {
     match *r {
         CEnum(min, max) => load_discr(bcx, scrutinee, min, max),
-        Univariant(*) => C_int(bcx.ccx(), 0),
-        General(ref cases) => load_discr(bcx, scrutinee, 0,
-                                         (cases.len() - 1) as int),
+        Univariant(*) => C_uint(bcx.ccx(), 0),
+        General(ref cases) => load_discr(bcx, scrutinee, 0, cases.len() - 1),
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
             ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee),
                  Type::enum_discrim(bcx.ccx()))
@@ -315,7 +314,7 @@ pub fn trans_get_discr(bcx: @mut Block, r: &Repr, scrutinee: ValueRef)
     }
 }
 
-fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: int, ptrfield: uint,
+fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: uint, ptrfield: uint,
                      scrutinee: ValueRef) -> ValueRef {
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
     let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield]));
@@ -324,7 +323,7 @@ fn nullable_bitdiscr(bcx: @mut Block, nonnull: &Struct, nndiscr: int, ptrfield:
 }
 
 /// Helper for cases where the discriminant is simply loaded.
-fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: int, max: int)
+fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: uint, max: uint)
     -> ValueRef {
     let ptr = GEPi(bcx, scrutinee, [0, 0]);
     if max + 1 == min {
@@ -348,16 +347,16 @@ fn load_discr(bcx: @mut Block, scrutinee: ValueRef, min: int, max: int)
  *
  * This should ideally be less tightly tied to `_match`.
  */
-pub fn trans_case(bcx: @mut Block, r: &Repr, discr: int) -> _match::opt_result {
+pub fn trans_case(bcx: @mut Block, r: &Repr, discr: uint) -> _match::opt_result {
     match *r {
         CEnum(*) => {
-            _match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
+            _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr)))
         }
         Univariant(*) => {
             bcx.ccx().sess.bug("no cases for univariants or structs")
         }
         General(*) => {
-            _match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
+            _match::single_result(rslt(bcx, C_uint(bcx.ccx(), discr)))
         }
         NullablePointer{ _ } => {
             assert!(discr == 0 || discr == 1);
@@ -371,11 +370,11 @@ pub fn trans_case(bcx: @mut Block, r: &Repr, discr: int) -> _match::opt_result {
  * representation.  The fields, if any, should then be initialized via
  * `trans_field_ptr`.
  */
-pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int) {
+pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: uint) {
     match *r {
         CEnum(min, max) => {
             assert!(min <= discr && discr <= max);
-            Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
+            Store(bcx, C_uint(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
         }
         Univariant(ref st, true) => {
             assert_eq!(discr, 0);
@@ -386,7 +385,7 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int) {
             assert_eq!(discr, 0);
         }
         General(*) => {
-            Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
+            Store(bcx, C_uint(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
         }
         NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
             if discr != nndiscr {
@@ -402,14 +401,14 @@ pub fn trans_start_init(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int) {
  * The number of fields in a given case; for use when obtaining this
  * information from the type or definition is less convenient.
  */
-pub fn num_args(r: &Repr, discr: int) -> uint {
+pub fn num_args(r: &Repr, discr: uint) -> uint {
     match *r {
         CEnum(*) => 0,
         Univariant(ref st, dtor) => {
             assert_eq!(discr, 0);
             st.fields.len() - (if dtor { 1 } else { 0 })
         }
-        General(ref cases) => cases[discr as uint].fields.len() - 1,
+        General(ref cases) => cases[discr].fields.len() - 1,
         NullablePointer{ nonnull: ref nonnull, nndiscr, nullfields: ref nullfields, _ } => {
             if discr == nndiscr { nonnull.fields.len() } else { nullfields.len() }
         }
@@ -417,7 +416,7 @@ pub fn num_args(r: &Repr, discr: int) -> uint {
 }
 
 /// Access a field, at a point when the value's case is known.
-pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int,
+pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: uint,
                        ix: uint) -> ValueRef {
     // Note: if this ever needs to generate conditionals (e.g., if we
     // decide to do some kind of cdr-coding-like non-unique repr
@@ -431,7 +430,7 @@ pub fn trans_field_ptr(bcx: @mut Block, r: &Repr, val: ValueRef, discr: int,
             struct_field_ptr(bcx, st, val, ix, false)
         }
         General(ref cases) => {
-            struct_field_ptr(bcx, &cases[discr as uint], val, ix + 1, true)
+            struct_field_ptr(bcx, &cases[discr], val, ix + 1, true)
         }
         NullablePointer{ nonnull: ref nonnull, nullfields: ref nullfields, nndiscr, _ } => {
             if (discr == nndiscr) {
@@ -495,22 +494,22 @@ pub fn trans_drop_flag_ptr(bcx: @mut Block, r: &Repr, val: ValueRef) -> ValueRef
  * this could be changed in the future to avoid allocating unnecessary
  * space after values of shorter-than-maximum cases.
  */
-pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int,
+pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: uint,
                    vals: &[ValueRef]) -> ValueRef {
     match *r {
         CEnum(min, max) => {
             assert_eq!(vals.len(), 0);
             assert!(min <= discr && discr <= max);
-            C_int(ccx, discr)
+            C_uint(ccx, discr)
         }
         Univariant(ref st, _dro) => {
             assert_eq!(discr, 0);
             C_struct(build_const_struct(ccx, st, vals))
         }
         General(ref cases) => {
-            let case = &cases[discr as uint];
+            let case = &cases[discr];
             let max_sz = cases.iter().transform(|x| x.size).max().unwrap();
-            let discr_ty = C_int(ccx, discr);
+            let discr_ty = C_uint(ccx, discr);
             let contents = build_const_struct(ccx, case,
                                               ~[discr_ty] + vals);
             C_struct(contents + &[padding(max_sz - case.size)])
@@ -582,13 +581,18 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
 
 /// Get the discriminant of a constant value.  (Not currently used.)
 pub fn const_get_discrim(ccx: &mut CrateContext, r: &Repr, val: ValueRef)
-    -> int {
+    -> uint {
     match *r {
-        CEnum(*) => const_to_int(val) as int,
+        CEnum(*) => const_to_uint(val) as uint,
         Univariant(*) => 0,
-        General(*) => const_to_int(const_get_elt(ccx, val, [0])) as int,
+        General(*) => const_to_uint(const_get_elt(ccx, val, [0])) as uint,
         NullablePointer{ nndiscr, ptrfield, _ } => {
-            if is_null(const_struct_field(ccx, val, ptrfield)) { 1 - nndiscr } else { nndiscr }
+            if is_null(const_struct_field(ccx, val, ptrfield)) {
+                /* subtraction as uint is ok because nndiscr is either 0 or 1 */
+                (1 - nndiscr) as uint
+            } else {
+                nndiscr
+            }
         }
     }
 }
@@ -601,7 +605,7 @@ pub fn const_get_discrim(ccx: &mut CrateContext, r: &Repr, val: ValueRef)
  * raw LLVM-level structs and arrays.)
  */
 pub fn const_get_field(ccx: &mut CrateContext, r: &Repr, val: ValueRef,
-                       _discr: int, ix: uint) -> ValueRef {
+                       _discr: uint, ix: uint) -> ValueRef {
     match *r {
         CEnum(*) => ccx.sess.bug("element access in C-like enum const"),
         Univariant(*) => const_struct_field(ccx, val, ix),
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index d3ae69b23da..50ea6537544 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -67,7 +67,6 @@ use middle::trans::type_::Type;
 
 use std::hash;
 use std::hashmap::{HashMap, HashSet};
-use std::int;
 use std::io;
 use std::libc::c_uint;
 use std::uint;
@@ -516,7 +515,8 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
             did
         };
         assert_eq!(did.crate, ast::local_crate);
-        let tsubsts = ty::substs { self_r: None, self_ty: None,
+        let tsubsts = ty::substs {regions: ty::ErasedRegions,
+                                  self_ty: None,
                                   tps: /*bad*/ substs.to_owned() };
         let (val, _) = monomorphize::monomorphic_fn(ccx,
                                                     did,
@@ -732,7 +732,7 @@ pub fn iter_structural_ty(cx: @mut Block, av: ValueRef, t: ty::t,
                   for (*variants).iter().advance |variant| {
                       let variant_cx =
                           sub_block(cx, ~"enum-iter-variant-" +
-                                    int::to_str(variant.disr_val));
+                                    uint::to_str(variant.disr_val));
                       let variant_cx =
                           iter_variant(variant_cx, repr, av, *variant,
                                        substs.tps, |x,y,z| f(x,y,z));
@@ -1979,7 +1979,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext,
                           _enum_id: ast::node_id,
                           variant: &ast::variant,
                           args: &[ast::variant_arg],
-                          disr: int,
+                          disr: uint,
                           param_substs: Option<@param_substs>,
                           llfndecl: ValueRef) {
     let _icx = push_ctxt("trans_enum_variant");
@@ -2028,7 +2028,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
     ccx: @mut CrateContext,
     ctor_id: ast::node_id,
     args: &[A],
-    disr: int,
+    disr: uint,
     param_substs: Option<@param_substs>,
     llfndecl: ValueRef)
 {
@@ -2628,7 +2628,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
                 }
             };
             unsafe {
-                llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, disr_val));
+                llvm::LLVMSetInitializer(discrim_gvar, C_uint(ccx, disr_val));
                 llvm::LLVMSetGlobalConstant(discrim_gvar, True);
             }
             ccx.discrims.insert(
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index d64615e5dc7..db849c78fa7 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -193,30 +193,15 @@ pub fn trans_fn_ref_with_vtables_to_callee(
                                                type_params, vtables))}
 }
 
-fn get_impl_resolutions(bcx: @mut Block,
-                        impl_id: ast::def_id)
-                         -> typeck::vtable_res {
-    if impl_id.crate == ast::local_crate {
-        bcx.ccx().maps.vtable_map.get_copy(&impl_id.node)
-    } else {
-        // XXX: This is a temporary hack to work around not properly
-        // exporting information about resolutions for impls.
-        // This doesn't actually work if the trait has param bounds,
-        // but it does allow us to survive the case when it does not.
-        let trait_ref = ty::impl_trait_ref(bcx.tcx(), impl_id).get();
-        @vec::from_elem(trait_ref.substs.tps.len(), @~[])
-    }
-}
-
 fn resolve_default_method_vtables(bcx: @mut Block,
                                   impl_id: ast::def_id,
                                   method: &ty::Method,
                                   substs: &ty::substs,
                                   impl_vtables: Option<typeck::vtable_res>)
-                                 -> typeck::vtable_res {
+                          -> (typeck::vtable_res, typeck::vtable_param_res) {
 
     // Get the vtables that the impl implements the trait at
-    let trait_vtables = get_impl_resolutions(bcx, impl_id);
+    let impl_res = ty::lookup_impl_vtables(bcx.tcx(), impl_id);
 
     // Build up a param_substs that we are going to resolve the
     // trait_vtables under.
@@ -224,11 +209,11 @@ fn resolve_default_method_vtables(bcx: @mut Block,
         tys: substs.tps.clone(),
         self_ty: substs.self_ty,
         vtables: impl_vtables,
-        self_vtable: None
+        self_vtables: None
     });
 
     let trait_vtables_fixed = resolve_vtables_under_param_substs(
-        bcx.tcx(), param_substs, trait_vtables);
+        bcx.tcx(), param_substs, impl_res.trait_vtables);
 
     // Now we pull any vtables for parameters on the actual method.
     let num_method_vtables = method.generics.type_param_defs.len();
@@ -241,7 +226,12 @@ fn resolve_default_method_vtables(bcx: @mut Block,
         None => vec::from_elem(num_method_vtables, @~[])
     };
 
-    @(*trait_vtables_fixed + method_vtables)
+    let param_vtables = @(*trait_vtables_fixed + method_vtables);
+
+    let self_vtables = resolve_param_vtables_under_param_substs(
+        bcx.tcx(), param_substs, impl_res.self_vtables);
+
+    (param_vtables, self_vtables)
 }
 
 
@@ -284,19 +274,14 @@ pub fn trans_fn_ref_with_vtables(
     // Polytype of the function item (may have type params)
     let fn_tpt = ty::lookup_item_type(tcx, def_id);
 
-    // For simplicity, we want to use the Subst trait when composing
-    // substitutions for default methods.  The subst trait does
-    // substitutions with regions, though, so we put a dummy self
-    // region parameter in to keep it from failing. This is a hack.
-    let substs = ty::substs { self_r: Some(ty::re_empty),
+    let substs = ty::substs { regions: ty::ErasedRegions,
                               self_ty: None,
                               tps: /*bad*/ type_params.to_owned() };
 
-
     // 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.
-    let (is_default, def_id, substs, self_vtable, vtables) =
+    let (is_default, def_id, substs, self_vtables, vtables) =
         match ty::provided_source(tcx, def_id) {
         None => (false, def_id, substs, None, vtables),
         Some(source_id) => {
@@ -319,20 +304,6 @@ pub fn trans_fn_ref_with_vtables(
                 .expect("could not find trait_ref for impl with \
                          default methods");
 
-            // Get all of the type params for the receiver
-            let param_defs = method.generics.type_param_defs;
-            let receiver_substs =
-                type_params.initn(param_defs.len()).to_owned();
-            let receiver_vtables = match vtables {
-                None => @~[],
-                Some(call_vtables) => {
-                    @call_vtables.initn(param_defs.len()).to_owned()
-                }
-            };
-
-            let self_vtable =
-                typeck::vtable_static(impl_id, receiver_substs,
-                                      receiver_vtables);
             // Compute the first substitution
             let first_subst = make_substs_for_receiver_types(
                 tcx, impl_id, trait_ref, method);
@@ -341,20 +312,22 @@ pub fn trans_fn_ref_with_vtables(
             let new_substs = first_subst.subst(tcx, &substs);
 
 
-            let vtables =
+            let (param_vtables, self_vtables) =
                 resolve_default_method_vtables(bcx, impl_id,
-                                               method, &new_substs, vtables);
+                                               method, &substs, vtables);
 
             debug!("trans_fn_with_vtables - default method: \
                     substs = %s, trait_subst = %s, \
                     first_subst = %s, new_subst = %s, \
-                    self_vtable = %s, vtables = %s",
+                    vtables = %s, \
+                    self_vtable = %s, param_vtables = %s",
                    substs.repr(tcx), trait_ref.substs.repr(tcx),
                    first_subst.repr(tcx), new_substs.repr(tcx),
-                   self_vtable.repr(tcx), vtables.repr(tcx));
+                   vtables.repr(tcx),
+                   self_vtables.repr(tcx), param_vtables.repr(tcx));
 
             (true, source_id,
-             new_substs, Some(self_vtable), Some(vtables))
+             new_substs, Some(self_vtables), Some(param_vtables))
         }
     };
 
@@ -400,7 +373,7 @@ pub fn trans_fn_ref_with_vtables(
 
         let (val, must_cast) =
             monomorphize::monomorphic_fn(ccx, def_id, &substs,
-                                         vtables, self_vtable,
+                                         vtables, self_vtables,
                                          Some(ref_id));
         let mut val = val;
         if must_cast && ref_id != 0 {
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 713939a5d83..690e488d219 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -133,7 +133,7 @@ pub struct param_substs {
     tys: ~[ty::t],
     self_ty: Option<ty::t>,
     vtables: Option<typeck::vtable_res>,
-    self_vtable: Option<typeck::vtable_origin>
+    self_vtables: Option<typeck::vtable_param_res>
 }
 
 impl param_substs {
@@ -850,6 +850,12 @@ pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
     }
 }
 
+pub fn is_const(v: ValueRef) -> bool {
+    unsafe {
+        llvm::LLVMIsConstant(v) == True
+    }
+}
+
 pub fn const_to_int(v: ValueRef) -> c_longlong {
     unsafe {
         llvm::LLVMConstIntGetSExtValue(v)
@@ -1020,15 +1026,26 @@ pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt,
                                           vts: typeck::vtable_res)
     -> typeck::vtable_res {
     @vts.iter().transform(|ds|
-      @ds.iter().transform(
-          |d| resolve_vtable_under_param_substs(tcx,
-                                                param_substs,
-                                                d))
-                          .collect::<~[typeck::vtable_origin]>())
-        .collect::<~[typeck::vtable_param_res]>()
+      resolve_param_vtables_under_param_substs(tcx,
+                                               param_substs,
+                                               *ds))
+        .collect()
+}
+
+pub fn resolve_param_vtables_under_param_substs(
+    tcx: ty::ctxt,
+    param_substs: Option<@param_substs>,
+    ds: typeck::vtable_param_res)
+    -> typeck::vtable_param_res {
+    @ds.iter().transform(
+        |d| resolve_vtable_under_param_substs(tcx,
+                                              param_substs,
+                                              d))
+        .collect()
 }
 
 
+
 // Apply the typaram substitutions in the FunctionContext to a vtable. This should
 // eliminate any vtable_params.
 pub fn resolve_vtable_in_fn_ctxt(fcx: &FunctionContext, vt: &typeck::vtable_origin)
@@ -1068,36 +1085,31 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
                 }
             }
         }
-        typeck::vtable_self(_trait_id) => {
-            match param_substs {
-                Some(@param_substs
-                     {self_vtable: Some(ref self_vtable), _}) => {
-                    (*self_vtable).clone()
-                }
-                _ => {
-                    tcx.sess.bug(fmt!(
-                        "resolve_vtable_in_fn_ctxt: asked to lookup but \
-                         no self_vtable in the fn_ctxt!"))
-                }
-            }
-        }
     }
 }
 
 pub fn find_vtable(tcx: ty::ctxt,
                    ps: &param_substs,
-                   n_param: uint,
+                   n_param: typeck::param_index,
                    n_bound: uint)
                    -> typeck::vtable_origin {
-    debug!("find_vtable(n_param=%u, n_bound=%u, ps=%s)",
+    debug!("find_vtable(n_param=%?, n_bound=%u, ps=%s)",
            n_param, n_bound, ps.repr(tcx));
 
-    ps.vtables.get()[n_param][n_bound].clone()
+    let param_bounds = match n_param {
+        typeck::param_self => ps.self_vtables.expect("self vtables missing"),
+        typeck::param_numbered(n) => {
+            let tables = ps.vtables
+                .expect("vtables missing where they are needed");
+            tables[n]
+        }
+    };
+    param_bounds[n_bound].clone()
 }
 
 pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs {
     substs {
-        self_r: Some(ty::re_bound(ty::br_self)),
+        regions: ty::ErasedRegions,
         self_ty: None,
         tps: tps
     }
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 15793ea747f..db9e3db2c0f 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -446,7 +446,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
               (expr::cast_enum, expr::cast_float)  => {
                 let repr = adt::represent_type(cx, basety);
                 let discr = adt::const_get_discrim(cx, repr, v);
-                let iv = C_int(cx, discr);
+                let iv = C_uint(cx, discr);
                 let ety_cast = expr::cast_type_kind(ety);
                 match ety_cast {
                     expr::cast_integral => {
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index 2b6c1d82418..8c87766bbbe 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -65,44 +65,36 @@ pub fn trans_if(bcx: @mut Block,
 
     let _icx = push_ctxt("trans_if");
 
-    match cond.node {
-        // `if true` and `if false` can be trans'd more efficiently,
-        // by dropping branches that are known to be impossible.
-        ast::expr_lit(@ref l) => match l.node {
-            ast::lit_bool(true) => {
-                // if true { .. } [else { .. }]
-                let then_bcx_in = scope_block(bcx, thn.info(), "if_true_then");
-                let then_bcx_out = trans_block(then_bcx_in, thn, dest);
-                let then_bcx_out = trans_block_cleanups(then_bcx_out,
-                                                        block_cleanups(then_bcx_in));
-                Br(bcx, then_bcx_in.llbb);
-                return then_bcx_out;
+    let Result {bcx, val: cond_val} =
+        expr::trans_to_datum(bcx, cond).to_result();
+
+    let cond_val = bool_to_i1(bcx, cond_val);
+
+    // Drop branches that are known to be impossible
+    if is_const(cond_val) && !is_undef(cond_val) {
+        if const_to_uint(cond_val) == 1 {
+            // if true { .. } [else { .. }]
+            return do with_scope(bcx, thn.info(), "if_true_then") |bcx| {
+                let bcx_out = trans_block(bcx, thn, dest);
+                trans_block_cleanups(bcx_out, block_cleanups(bcx))
             }
-            ast::lit_bool(false) => {
-                match els {
-                    // if false { .. } else { .. }
-                    Some(elexpr) => {
-                        let (else_bcx_in, else_bcx_out) =
-                            trans_if_else(bcx, elexpr, dest, "if_false_else");
-                        Br(bcx, else_bcx_in.llbb);
-                        return else_bcx_out;
+        } else {
+            match els {
+                // if false { .. } else { .. }
+                Some(elexpr) => {
+                    return do with_scope(bcx, elexpr.info(), "if_false_then") |bcx| {
+                        let bcx_out = trans_if_else(bcx, elexpr, dest);
+                        trans_block_cleanups(bcx_out, block_cleanups(bcx))
                     }
-                    // if false { .. }
-                    None => return bcx,
                 }
+                // if false { .. }
+                None => return bcx,
             }
-            _ => {}
-        },
-        _ => {}
+        }
     }
 
-    let Result {bcx, val: cond_val} =
-        expr::trans_to_datum(bcx, cond).to_result();
-
     let then_bcx_in = scope_block(bcx, thn.info(), "then");
 
-    let cond_val = bool_to_i1(bcx, cond_val);
-
     let then_bcx_out = trans_block(then_bcx_in, thn, dest);
     let then_bcx_out = trans_block_cleanups(then_bcx_out,
                                             block_cleanups(then_bcx_in));
@@ -113,7 +105,8 @@ pub fn trans_if(bcx: @mut Block,
     // 'else' context
     let (else_bcx_in, next_bcx) = match els {
       Some(elexpr) => {
-          let (else_bcx_in, else_bcx_out) = trans_if_else(bcx, elexpr, dest, "else");
+          let else_bcx_in = scope_block(bcx, elexpr.info(), "else");
+          let else_bcx_out = trans_if_else(else_bcx_in, elexpr, dest);
           (else_bcx_in, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
       }
       _ => {
@@ -131,9 +124,8 @@ pub fn trans_if(bcx: @mut Block,
     return next_bcx;
 
     // trans `else [ if { .. } ... | { .. } ]`
-    fn trans_if_else(bcx: @mut Block, elexpr: @ast::expr,
-                     dest: expr::Dest, scope_name: &str) -> (@mut Block, @mut Block) {
-        let else_bcx_in = scope_block(bcx, elexpr.info(), scope_name);
+    fn trans_if_else(else_bcx_in: @mut Block, elexpr: @ast::expr,
+                     dest: expr::Dest) -> @mut Block {
         let else_bcx_out = match elexpr.node {
             ast::expr_if(_, _, _) => {
                 let elseif_blk = ast_util::block_from_expr(elexpr);
@@ -143,11 +135,9 @@ pub fn trans_if(bcx: @mut Block,
                 trans_block(else_bcx_in, blk, dest)
             }
             // would be nice to have a constraint on ifs
-            _ => bcx.tcx().sess.bug("strange alternative in if")
+            _ => else_bcx_in.tcx().sess.bug("strange alternative in if")
         };
-        let else_bcx_out = trans_block_cleanups(else_bcx_out,
-                                                block_cleanups(else_bcx_in));
-        (else_bcx_in, else_bcx_out)
+        trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
     }
 }
 
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index f552eded163..c038ca710aa 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1083,7 +1083,7 @@ pub fn trans_local_var(bcx: @mut Block, def: ast::def) -> Datum {
 pub fn with_field_tys<R>(tcx: ty::ctxt,
                          ty: ty::t,
                          node_id_opt: Option<ast::node_id>,
-                         op: &fn(int, (&[ty::field])) -> R) -> R {
+                         op: &fn(uint, (&[ty::field])) -> R) -> R {
     match ty::get(ty).sty {
         ty::ty_struct(did, ref substs) => {
             op(0, struct_fields(tcx, did, substs))
@@ -1200,7 +1200,7 @@ struct StructBaseInfo {
  * - `optbase` contains information on the base struct (if any) from
  * which remaining fields are copied; see comments on `StructBaseInfo`.
  */
-fn trans_adt(bcx: @mut Block, repr: &adt::Repr, discr: int,
+fn trans_adt(bcx: @mut Block, repr: &adt::Repr, discr: uint,
              fields: &[(uint, @ast::expr)],
              optbase: Option<StructBaseInfo>,
              dest: Dest) -> @mut Block {
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index a65999ff2aa..9228f20513b 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -147,46 +147,13 @@ pub fn trans_method_callee(bcx: @mut Block,
                            mentry: typeck::method_map_entry)
                            -> Callee {
     let _icx = push_ctxt("impl::trans_method_callee");
-    let tcx = bcx.tcx();
 
     debug!("trans_method_callee(callee_id=%?, this=%s, mentry=%s)",
            callee_id,
            bcx.expr_to_str(this),
            mentry.repr(bcx.tcx()));
 
-    // Replace method_self with method_static here.
-    let mut origin = mentry.origin;
-    match origin {
-        typeck::method_super(trait_id, method_index) => {
-            // <self_ty> is the self type for this method call
-            let self_ty = node_id_type(bcx, this.id);
-            // <impl_id> is the ID of the implementation of
-            // trait <trait_id> for type <self_ty>
-            let impl_id = ty::bogus_get_impl_id_from_ty(tcx, trait_id, self_ty);
-            // Get the supertrait's methods
-            let supertrait_method_def_ids = ty::trait_method_def_ids(tcx, trait_id);
-            // Make sure to fail with a readable error message if
-            // there's some internal error here
-            if !(method_index < supertrait_method_def_ids.len()) {
-                tcx.sess.bug("trans_method_callee: supertrait method \
-                              index is out of bounds");
-            }
-            // Get the method name using the method index in the origin
-            let method_name =
-                ty::method(tcx, supertrait_method_def_ids[method_index]).ident;
-            // Now that we know the impl ID, we can look up the method
-            // ID from its name
-            origin = typeck::method_static(
-                method_with_name(bcx.ccx(), impl_id, method_name));
-        }
-        typeck::method_self(*) |
-        typeck::method_static(*) | typeck::method_param(*) |
-        typeck::method_trait(*) => {}
-    }
-
-    debug!("origin=%?", origin);
-
-    match origin {
+    match mentry.origin {
         typeck::method_static(did) => {
             let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
             let mut temp_cleanups = ~[];
@@ -210,7 +177,8 @@ pub fn trans_method_callee(bcx: @mut Block,
         }) => {
             match bcx.fcx.param_substs {
                 Some(substs) => {
-                    let vtbl = find_vtable(bcx.tcx(), substs, p, b);
+                    let vtbl = find_vtable(bcx.tcx(), substs,
+                                           p, b);
                     trans_monomorphized_callee(bcx, callee_id, this, mentry,
                                                trait_id, off, vtbl)
                 }
@@ -219,24 +187,6 @@ pub fn trans_method_callee(bcx: @mut Block,
             }
         }
 
-        typeck::method_self(trait_id, method_index) => {
-            match bcx.fcx.param_substs {
-                Some(@param_substs
-                     {self_vtable: Some(ref vtbl), _}) => {
-                    trans_monomorphized_callee(bcx,
-                                               callee_id,
-                                               this,
-                                               mentry,
-                                               trait_id,
-                                               method_index,
-                                               (*vtbl).clone())
-                }
-                _ => {
-                    fail!("trans_method_callee: missing self_vtable")
-                }
-            }
-        }
-
         typeck::method_trait(_, off, store) => {
             trans_trait_callee(bcx,
                                callee_id,
@@ -245,9 +195,6 @@ pub fn trans_method_callee(bcx: @mut Block,
                                store,
                                mentry.explicit_self)
         }
-        typeck::method_super(*) => {
-            fail!("method_super should have been handled above")
-        }
     }
 }
 
@@ -402,9 +349,6 @@ pub fn trans_monomorphized_callee(bcx: @mut Block,
       typeck::vtable_param(*) => {
           fail!("vtable_param left in monomorphized function's vtable substs");
       }
-      typeck::vtable_self(*) => {
-          fail!("vtable_self left in monomorphized function's vtable substs");
-      }
     };
 
 }
@@ -611,7 +555,7 @@ pub fn vtable_id(ccx: @mut CrateContext,
                 tys: (*substs).clone(),
                 vtables: Some(sub_vtables),
                 self_ty: None,
-                self_vtable: None
+                self_vtables: None
             };
 
             monomorphize::make_mono_id(
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index 789532abc61..9852e6b09b7 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -41,7 +41,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
                       fn_id: ast::def_id,
                       real_substs: &ty::substs,
                       vtables: Option<typeck::vtable_res>,
-                      self_vtable: Option<typeck::vtable_origin>,
+                      self_vtables: Option<typeck::vtable_param_res>,
                       ref_id: Option<ast::node_id>)
     -> (ValueRef, bool)
 {
@@ -54,7 +54,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
            fn_id.repr(ccx.tcx),
            real_substs.repr(ccx.tcx),
            vtables.repr(ccx.tcx),
-           self_vtable.repr(ccx.tcx),
+           self_vtables.repr(ccx.tcx),
            ref_id);
 
     assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t)));
@@ -72,7 +72,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
         tys: real_substs.tps.map(|x| do_normalize(x)),
         vtables: vtables,
         self_ty: real_substs.self_ty.map(|x| do_normalize(x)),
-        self_vtable: self_vtable
+        self_vtables: self_vtables
     };
 
     for real_substs.tps.iter().advance |s| { assert!(!ty::type_has_params(*s)); }
@@ -371,8 +371,7 @@ pub fn make_mono_id(ccx: @mut CrateContext,
       Some(vts) => {
         debug!("make_mono_id vtables=%s substs=%s",
                vts.repr(ccx.tcx), substs.tys.repr(ccx.tcx));
-        let self_vtables = substs.self_vtable.map(|vtbl| @~[(*vtbl).clone()]);
-        let vts_iter = self_vtables.iter().chain_(vts.iter());
+        let vts_iter = substs.self_vtables.iter().chain_(vts.iter());
         vts_iter.zip(substs_iter).transform(|(vtable, subst)| {
             let v = vtable.map(|vt| meth::vtable_id(ccx, vt));
             (*subst, if !v.is_empty() { Some(@v) } else { None })
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 84b001953e0..3d23828979f 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -321,7 +321,7 @@ impl Reflector {
                 for variants.iter().enumerate().advance |(i, v)| {
                     let name = ccx.sess.str_of(v.name);
                     let variant_args = ~[this.c_uint(i),
-                                         this.c_int(v.disr_val),
+                                         this.c_uint(v.disr_val),
                                          this.c_uint(v.args.len()),
                                          this.c_slice(name)];
                     do this.bracketed("enum_variant", variant_args) |this| {
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 4e15b4bc229..b743f2e9401 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -17,6 +17,7 @@ use util::ppaux;
 use middle::trans::type_::Type;
 
 use syntax::ast;
+use syntax::opt_vec;
 
 pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: &ty::t) -> bool {
     !ty::type_is_immediate(ccx.tcx, *arg_ty)
@@ -312,7 +313,8 @@ pub fn llvm_type_name(cx: &CrateContext,
         a_struct => { "struct" }
         an_enum => { "enum" }
     };
-    let tstr = ppaux::parameterized(cx.tcx, ty::item_path_str(cx.tcx, did), None, tps);
+    let tstr = ppaux::parameterized(cx.tcx, ty::item_path_str(cx.tcx, did),
+                                    &ty::NonerasedRegions(opt_vec::Empty), tps);
     if did.crate == 0 {
         fmt!("%s.%s", name, tstr)
     } else {
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 4d5d597d382..aa19af01893 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -274,13 +274,12 @@ pub fn mark_for_method_call(cx: &Context, e_id: node_id, callee_id: node_id) {
                   opt_static_did = Some(did);
               }
               typeck::method_param(typeck::method_param {
-                  param_num: param,
+                  param_num: typeck::param_numbered(param),
                   _
               }) => {
                 cx.uses[param] |= use_tydesc;
               }
-              typeck::method_trait(*) | typeck::method_self(*)
-                  | typeck::method_super(*) => (),
+              _ => (),
             }
         }
     }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 7eea20175f9..9b3df349f1e 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -49,7 +49,7 @@ use syntax::opt_vec;
 use syntax::abi::AbiSet;
 use syntax;
 
-pub static INITIAL_DISCRIMINANT_VALUE: int = 0;
+pub static INITIAL_DISCRIMINANT_VALUE: uint = 0;
 
 // Data types
 
@@ -317,6 +317,9 @@ struct ctxt_ {
     // some point. Local variable definitions not in this set can be warned
     // about.
     used_mut_nodes: @mut HashSet<ast::node_id>,
+
+    // vtable resolution information for impl declarations
+    impl_vtables: typeck::impl_vtable_map
 }
 
 pub enum tbox_flag {
@@ -486,7 +489,15 @@ pub enum bound_region {
     br_cap_avoid(ast::node_id, @bound_region),
 }
 
-type opt_region = Option<Region>;
+/**
+ * Represents the values to use when substituting lifetime parameters.
+ * If the value is `ErasedRegions`, then this subst is occurring during
+ * trans, and all region parameters will be replaced with `ty::re_static`. */
+#[deriving(Clone, Eq, IterBytes)]
+pub enum RegionSubsts {
+    ErasedRegions,
+    NonerasedRegions(OptVec<ty::Region>)
+}
 
 /**
  * The type substs represents the kinds of things that can be substituted to
@@ -507,9 +518,9 @@ type opt_region = Option<Region>;
  *   always substituted away to the implementing type for a trait. */
 #[deriving(Clone, Eq, IterBytes)]
 pub struct substs {
-    self_r: opt_region,
     self_ty: Option<ty::t>,
-    tps: ~[t]
+    tps: ~[t],
+    regions: RegionSubsts,
 }
 
 mod primitives {
@@ -911,6 +922,7 @@ pub fn mk_ctxt(s: session::Session,
         impls:  @mut HashMap::new(),
         used_unsafe: @mut HashSet::new(),
         used_mut_nodes: @mut HashSet::new(),
+        impl_vtables: @mut HashMap::new(),
      }
 }
 
@@ -948,7 +960,14 @@ fn mk_t(cx: ctxt, st: sty) -> t {
     fn sflags(substs: &substs) -> uint {
         let mut f = 0u;
         for substs.tps.iter().advance |tt| { f |= get(*tt).flags; }
-        for substs.self_r.iter().advance |r| { f |= rflags(*r) }
+        match substs.regions {
+            ErasedRegions => {}
+            NonerasedRegions(ref regions) => {
+                for regions.iter().advance |r| {
+                    f |= rflags(*r)
+                }
+            }
+        }
         return f;
     }
     match &st {
@@ -1286,7 +1305,7 @@ pub fn fold_bare_fn_ty(fty: &BareFnTy, fldop: &fn(t) -> t) -> BareFnTy {
 
 fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
     fn fold_substs(substs: &substs, fldop: &fn(t) -> t) -> substs {
-        substs {self_r: substs.self_r,
+        substs {regions: substs.regions.clone(),
                 self_ty: substs.self_ty.map(|t| fldop(*t)),
                 tps: substs.tps.map(|t| fldop(*t))}
     }
@@ -1378,8 +1397,15 @@ pub fn fold_regions_and_ty(
         fldr: &fn(r: Region) -> Region,
         fldt: &fn(t: t) -> t)
      -> substs {
+        let regions = match substs.regions {
+            ErasedRegions => ErasedRegions,
+            NonerasedRegions(ref regions) => {
+                NonerasedRegions(regions.map(|r| fldr(*r)))
+            }
+        };
+
         substs {
-            self_r: substs.self_r.map(|r| fldr(*r)),
+            regions: regions,
             self_ty: substs.self_ty.map(|t| fldt(*t)),
             tps: substs.tps.map(|t| fldt(*t))
         }
@@ -1478,8 +1504,13 @@ pub fn subst_tps(cx: ctxt, tps: &[t], self_ty_opt: Option<t>, typ: t) -> t {
 }
 
 pub fn substs_is_noop(substs: &substs) -> bool {
+    let regions_is_noop = match substs.regions {
+        ErasedRegions => false, // may be used to canonicalize
+        NonerasedRegions(ref regions) => regions.is_empty()
+    };
+
     substs.tps.len() == 0u &&
-        substs.self_r.is_none() &&
+        regions_is_noop &&
         substs.self_ty.is_none()
 }
 
@@ -3061,9 +3092,7 @@ pub fn method_call_type_param_defs(tcx: ctxt,
           typeck::method_param(typeck::method_param {
               trait_id: trt_id,
               method_num: n_mth, _}) |
-          typeck::method_trait(trt_id, n_mth, _) |
-          typeck::method_self(trt_id, n_mth) |
-          typeck::method_super(trt_id, n_mth) => {
+          typeck::method_trait(trt_id, n_mth, _) => {
             // ...trait methods bounds, in contrast, include only the
             // method bounds, so we must preprend the tps from the
             // trait itself.  This ought to be harmonized.
@@ -3689,7 +3718,7 @@ pub struct VariantInfo {
     ctor_ty: t,
     name: ast::ident,
     id: ast::def_id,
-    disr_val: int,
+    disr_val: uint,
     vis: visibility
 }
 
@@ -3700,7 +3729,7 @@ impl VariantInfo {
     /// Does not do any caching of the value in the type context.
     pub fn from_ast_variant(cx: ctxt,
                             ast_variant: &ast::variant,
-                            discriminant: int) -> VariantInfo {
+                            discriminant: uint) -> VariantInfo {
 
         let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
 
@@ -3894,7 +3923,7 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[@VariantInfo] {
                     node: ast::item_enum(ref enum_definition, _),
                     _
                 }, _) => {
-            let mut last_discriminant: Option<int> = None;
+            let mut last_discriminant: Option<uint> = None;
             @enum_definition.variants.iter().transform(|variant| {
 
                 let mut discriminant = match last_discriminant {
@@ -3904,7 +3933,8 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[@VariantInfo] {
 
                 match variant.node.disr_expr {
                     Some(e) => match const_eval::eval_const_expr_partial(&cx, e) {
-                        Ok(const_eval::const_int(val)) => discriminant = val as int,
+                        Ok(const_eval::const_int(val)) => discriminant = val as uint,
+                        Ok(const_eval::const_uint(val)) => discriminant = val as uint,
                         Ok(_) => {
                             cx.sess.span_err(e.span, "expected signed integer constant");
                         }
@@ -3955,6 +3985,14 @@ pub fn lookup_item_type(cx: ctxt,
         || csearch::get_type(cx, did))
 }
 
+pub fn lookup_impl_vtables(cx: ctxt,
+                           did: ast::def_id)
+                     -> typeck::impl_res {
+    lookup_locally_or_in_crate_store(
+        "impl_vtables", did, cx.impl_vtables,
+        || csearch::get_impl_vtables(cx, did) )
+}
+
 /// Given the did of a trait, returns its canonical trait ref.
 pub fn lookup_trait_def(cx: ctxt, did: ast::def_id) -> @ty::TraitDef {
     match cx.trait_defs.find(&did) {
@@ -4227,30 +4265,33 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
             })
         }
 
-        ty_enum(did, ref r) =>
-            match (*r).self_r {
-                Some(_) =>
-                    // Use re_static since trans doesn't care about regions
-                    mk_enum(cx, did,
-                     substs {
-                        self_r: Some(ty::re_static),
-                        self_ty: None,
-                        tps: (*r).tps.clone()
-                     }),
-                None =>
+        ty_enum(did, ref r) => {
+            match (*r).regions {
+                NonerasedRegions(_) => {
+                    // trans doesn't care about regions
+                    mk_enum(cx, did, substs {regions: ty::ErasedRegions,
+                                             self_ty: None,
+                                             tps: (*r).tps.clone()})
+                }
+                ErasedRegions => {
                     t
-            },
+                }
+            }
+        }
 
-        ty_struct(did, ref r) =>
-            match (*r).self_r {
-              Some(_) =>
-                // Ditto.
-                mk_struct(cx, did, substs {self_r: Some(ty::re_static),
-                                           self_ty: None,
-                                           tps: (*r).tps.clone()}),
-              None =>
-                t
-            },
+        ty_struct(did, ref r) => {
+            match (*r).regions {
+                NonerasedRegions(_) => {
+                    // Ditto.
+                    mk_struct(cx, did, substs {regions: ty::ErasedRegions,
+                                               self_ty: None,
+                                               tps: (*r).tps.clone()})
+                }
+                ErasedRegions => {
+                    t
+                }
+            }
+        }
 
         _ =>
             t
@@ -4338,9 +4379,9 @@ pub fn determine_inherited_purity(parent: (ast::purity, ast::node_id),
 // relation on the supertraits from each bounded trait's constraint
 // list.
 pub fn each_bound_trait_and_supertraits(tcx: ctxt,
-                                        bounds: &ParamBounds,
+                                        bounds: &[@TraitRef],
                                         f: &fn(@TraitRef) -> bool) -> bool {
-    for bounds.trait_bounds.iter().advance |&bound_trait_ref| {
+    for bounds.iter().advance |&bound_trait_ref| {
         let mut supertrait_set = HashMap::new();
         let mut trait_refs = ~[];
         let mut i = 0;
@@ -4382,38 +4423,14 @@ pub fn count_traits_and_supertraits(tcx: ctxt,
                                     type_param_defs: &[TypeParameterDef]) -> uint {
     let mut total = 0;
     for type_param_defs.iter().advance |type_param_def| {
-        for each_bound_trait_and_supertraits(tcx, type_param_def.bounds) |_| {
+        for each_bound_trait_and_supertraits(
+            tcx, type_param_def.bounds.trait_bounds) |_| {
             total += 1;
         }
     }
     return total;
 }
 
-// Given a trait and a type, returns the impl of that type.
-// This is broken, of course, by parametric impls. This used to use
-// a table specifically for this mapping, but I removed that table.
-// This is only used when calling a supertrait method from a default method,
-// and should go away once I fix how that works. -sully
-pub fn bogus_get_impl_id_from_ty(tcx: ctxt,
-                                 trait_id: def_id, self_ty: t) -> def_id {
-    match tcx.trait_impls.find(&trait_id) {
-        Some(ty_to_impl) => {
-            for ty_to_impl.iter().advance |imp| {
-                let impl_ty = tcx.tcache.get_copy(&imp.did);
-                if impl_ty.ty == self_ty { return imp.did; }
-            }
-            // try autoderef!
-            match deref(tcx, self_ty, false) {
-                Some(some_ty) =>
-                  bogus_get_impl_id_from_ty(tcx, trait_id, some_ty.ty),
-                None => tcx.sess.bug("get_impl_id: no impl of trait for \
-                                      this type")
-            }
-        },
-        None => tcx.sess.bug("get_impl_id: trait isn't in trait_impls")
-    }
-}
-
 pub fn get_tydesc_ty(tcx: ctxt) -> Result<t, ~str> {
     do tcx.lang_items.require(TyDescStructLangItem).map |tydesc_lang_item| {
         tcx.intrinsic_defs.find_copy(tydesc_lang_item)
@@ -4434,7 +4451,7 @@ pub fn visitor_object_ty(tcx: ctxt) -> Result<(@TraitRef, t), ~str> {
         Err(s) => { return Err(s); }
     };
     let substs = substs {
-        self_r: None,
+        regions: ty::NonerasedRegions(opt_vec::Empty),
         self_ty: None,
         tps: ~[]
     };
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 28595e5af51..a506142a971 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -150,26 +150,27 @@ 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 self_r = match (&decl_generics.region_param, &path.rp) {
-      (&None, &None) => {
-        None
-      }
-      (&None, &Some(_)) => {
-        tcx.sess.span_err(
-            path.span,
-            fmt!("no region bound is allowed on `%s`, \
-                  which is not declared as containing region pointers",
-                 ty::item_path_str(tcx, def_id)));
-        None
-      }
-      (&Some(_), &None) => {
-        let res = rscope.anon_region(path.span);
-        let r = get_region_reporting_err(this.tcx(), path.span, &None, res);
-        Some(r)
-      }
-      (&Some(_), &Some(_)) => {
-        Some(ast_region_to_region(this, rscope, path.span, &path.rp))
-      }
+    let regions = match (&decl_generics.region_param, &path.rp) {
+        (&None, &None) => {
+            opt_vec::Empty
+        }
+        (&None, &Some(_)) => {
+            tcx.sess.span_err(
+                path.span,
+                fmt!("no region bound is allowed on `%s`, \
+                      which is not declared as containing region pointers",
+                     ty::item_path_str(tcx, def_id)));
+            opt_vec::Empty
+        }
+        (&Some(_), &None) => {
+            let res = rscope.anon_region(path.span);
+            let r = get_region_reporting_err(this.tcx(), path.span, &None, res);
+            opt_vec::with(r)
+        }
+        (&Some(_), &Some(_)) => {
+            opt_vec::with(
+                ast_region_to_region(this, rscope, path.span, &path.rp))
+        }
     };
 
     // Convert the type parameters supplied by the user.
@@ -181,7 +182,7 @@ fn ast_path_substs<AC:AstConv,RS:region_scope + Clone + 'static>(
     }
     let tps = path.types.map(|a_t| ast_ty_to_ty(this, rscope, a_t));
 
-    substs {self_r:self_r, self_ty:self_ty, tps:tps}
+    substs {regions:ty::NonerasedRegions(regions), self_ty:self_ty, tps:tps}
 }
 
 pub fn ast_path_to_substs_and_ty<AC:AstConv,
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 8d546366846..a4d93586327 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -90,7 +90,8 @@ use middle::typeck::check::vtable;
 use middle::typeck::check;
 use middle::typeck::infer;
 use middle::typeck::{method_map_entry, method_origin, method_param};
-use middle::typeck::{method_self, method_static, method_trait, method_super};
+use middle::typeck::{method_static, method_trait};
+use middle::typeck::{param_numbered, param_self, param_index};
 use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
 use util::common::indenter;
 
@@ -328,64 +329,6 @@ impl<'self> LookupContext<'self> {
         }
     }
 
-    pub fn push_inherent_candidates_from_param(&self,
-                                               rcvr_ty: ty::t,
-                                               param_ty: param_ty) {
-        debug!("push_inherent_candidates_from_param(param_ty=%?)",
-               param_ty);
-        let _indenter = indenter();
-
-        let tcx = self.tcx();
-        let mut next_bound_idx = 0; // count only trait bounds
-        let type_param_def = match tcx.ty_param_defs.find(&param_ty.def_id.node) {
-            Some(t) => t,
-            None => {
-                tcx.sess.span_bug(
-                    self.expr.span,
-                    fmt!("No param def for %?", param_ty));
-            }
-        };
-
-        for ty::each_bound_trait_and_supertraits(tcx, type_param_def.bounds)
-            |bound_trait_ref|
-        {
-            let this_bound_idx = next_bound_idx;
-            next_bound_idx += 1;
-
-            let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
-            let pos = {
-                match trait_methods.iter().position(|m| {
-                    m.explicit_self != ast::sty_static &&
-                        m.ident == self.m_name })
-                {
-                    Some(pos) => pos,
-                    None => {
-                        debug!("trait doesn't contain method: %?",
-                               bound_trait_ref.def_id);
-                        loop; // check next trait or bound
-                    }
-                }
-            };
-            let method = trait_methods[pos];
-
-            let cand = Candidate {
-                rcvr_ty: rcvr_ty,
-                rcvr_substs: bound_trait_ref.substs.clone(),
-                method_ty: method,
-                origin: method_param(
-                    method_param {
-                        trait_id: bound_trait_ref.def_id,
-                        method_num: pos,
-                        param_num: param_ty.idx,
-                        bound_num: this_bound_idx,
-                    })
-            };
-
-            debug!("pushing inherent candidate for param: %?", cand);
-            self.inherent_candidates.push(cand);
-        }
-    }
-
     pub fn push_inherent_candidates_from_trait(&self,
                                                self_ty: ty::t,
                                                did: def_id,
@@ -438,69 +381,87 @@ impl<'self> LookupContext<'self> {
         });
     }
 
+    pub fn push_inherent_candidates_from_param(&self,
+                                               rcvr_ty: ty::t,
+                                               param_ty: param_ty) {
+        debug!("push_inherent_candidates_from_param(param_ty=%?)",
+               param_ty);
+        let _indenter = indenter();
+
+        let tcx = self.tcx();
+        let type_param_def = match tcx.ty_param_defs.find(&param_ty.def_id.node) {
+            Some(t) => t,
+            None => {
+                tcx.sess.span_bug(
+                    self.expr.span,
+                    fmt!("No param def for %?", param_ty));
+            }
+        };
+
+        self.push_inherent_candidates_from_bounds(
+            rcvr_ty, type_param_def.bounds.trait_bounds,
+            param_numbered(param_ty.idx));
+    }
+
+
     pub fn push_inherent_candidates_from_self(&self,
                                               self_ty: ty::t,
                                               did: def_id) {
-        struct MethodInfo {
-            method_ty: @ty::Method,
-            trait_def_id: ast::def_id,
-            index: uint,
-            trait_ref: @ty::TraitRef
-        }
+        let tcx = self.tcx();
+
+        let trait_ref = ty::lookup_trait_def(tcx, did).trait_ref;
+        self.push_inherent_candidates_from_bounds(
+            self_ty, &[trait_ref], param_self);
+    }
 
+    pub fn push_inherent_candidates_from_bounds(&self,
+                                                self_ty: ty::t,
+                                                bounds: &[@TraitRef],
+                                                param: param_index) {
         let tcx = self.tcx();
-        // First, try self methods
-        let mut method_info: Option<MethodInfo> = None;
-        let methods = ty::trait_methods(tcx, did);
-        match methods.iter().position(|m| m.ident == self.m_name) {
-            Some(i) => {
-                method_info = Some(MethodInfo {
-                    method_ty: methods[i],
-                    index: i,
-                    trait_def_id: did,
-                    trait_ref: ty::lookup_trait_def(tcx, did).trait_ref
-                });
-            }
-            None => ()
-        }
-        // No method found yet? Check each supertrait
-        if method_info.is_none() {
-            for ty::trait_supertraits(tcx, did).iter().advance |trait_ref| {
-                let supertrait_methods =
-                    ty::trait_methods(tcx, trait_ref.def_id);
-                match supertrait_methods.iter().position(|m| m.ident == self.m_name) {
-                    Some(i) => {
-                        method_info = Some(MethodInfo {
-                            method_ty: supertrait_methods[i],
-                            index: i,
-                            trait_def_id: trait_ref.def_id,
-                            trait_ref: *trait_ref
-                        });
-                        break;
+        let mut next_bound_idx = 0; // count only trait bounds
+
+        for ty::each_bound_trait_and_supertraits(tcx, bounds)
+            |bound_trait_ref|
+        {
+            let this_bound_idx = next_bound_idx;
+            next_bound_idx += 1;
+
+            let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
+            let pos = {
+                match trait_methods.iter().position(|m| {
+                    m.explicit_self != ast::sty_static &&
+                        m.ident == self.m_name })
+                {
+                    Some(pos) => pos,
+                    None => {
+                        debug!("trait doesn't contain method: %?",
+                               bound_trait_ref.def_id);
+                        loop; // check next trait or bound
                     }
-                    None => ()
                 }
-            }
-        }
-        match method_info {
-            Some(ref info) => {
-                // We've found a method -- return it
-                let origin = if did == info.trait_def_id {
-                    method_self(info.trait_def_id, info.index)
-                } else {
-                    method_super(info.trait_def_id, info.index)
-                };
-                self.inherent_candidates.push(Candidate {
-                    rcvr_ty: self_ty,
-                    rcvr_substs: info.trait_ref.substs.clone(),
-                    method_ty: info.method_ty,
-                    origin: origin
-                });
-            }
-            _ => return
+            };
+            let method = trait_methods[pos];
+
+            let cand = Candidate {
+                rcvr_ty: self_ty,
+                rcvr_substs: bound_trait_ref.substs.clone(),
+                method_ty: method,
+                origin: method_param(
+                    method_param {
+                        trait_id: bound_trait_ref.def_id,
+                        method_num: pos,
+                        param_num: param,
+                        bound_num: this_bound_idx,
+                    })
+            };
+
+            debug!("pushing inherent candidate for param: %?", cand);
+            self.inherent_candidates.push(cand);
         }
     }
 
+
     pub fn push_inherent_impl_candidates_for_type(&self, did: def_id) {
         let opt_impl_infos = self.tcx().inherent_impls.find(&did);
         for opt_impl_infos.iter().advance |impl_infos| {
@@ -938,7 +899,7 @@ impl<'self> LookupContext<'self> {
         // which is equal to the class tps + the method tps.
         let all_substs = substs {
             tps: vec::append(candidate.rcvr_substs.tps.clone(), m_substs),
-            self_r: candidate.rcvr_substs.self_r,
+            regions: candidate.rcvr_substs.regions.clone(),
             self_ty: candidate.rcvr_substs.self_ty,
         };
 
@@ -1005,14 +966,13 @@ impl<'self> LookupContext<'self> {
         /*!
          *
          * There are some limitations to calling functions through a
-         * traint instance, because (a) the self type is not known
+         * trait instance, because (a) the self type is not known
          * (that's the whole point of a trait instance, after all, to
          * obscure the self type) and (b) the call must go through a
          * vtable and hence cannot be monomorphized. */
 
         match candidate.origin {
-            method_static(*) | method_param(*) |
-                method_self(*) | method_super(*) => {
+            method_static(*) | method_param(*) => {
                 return; // not a call to a trait instance
             }
             method_trait(*) => {}
@@ -1036,10 +996,11 @@ impl<'self> LookupContext<'self> {
         // No code can call the finalize method explicitly.
         let bad;
         match candidate.origin {
-            method_static(method_id) | method_self(method_id, _)
-                | method_super(method_id, _) => {
+            method_static(method_id) => {
                 bad = self.tcx().destructors.contains(&method_id);
             }
+            // XXX: does this properly enforce this on everything now
+            // that self has been merged in? -sully
             method_param(method_param { trait_id: trait_id, _ }) |
             method_trait(trait_id, _, _) => {
                 bad = self.tcx().destructor_for_type.contains_key(&trait_id);
@@ -1158,8 +1119,7 @@ impl<'self> LookupContext<'self> {
             method_param(ref mp) => {
                 type_of_trait_method(self.tcx(), mp.trait_id, mp.method_num)
             }
-            method_trait(did, idx, _) | method_self(did, idx) |
-                method_super(did, idx) => {
+            method_trait(did, idx, _) => {
                 type_of_trait_method(self.tcx(), did, idx)
             }
         };
@@ -1180,8 +1140,7 @@ impl<'self> LookupContext<'self> {
             method_param(ref mp) => {
                 self.report_param_candidate(idx, (*mp).trait_id)
             }
-            method_trait(trait_did, _, _) | method_self(trait_did, _)
-                | method_super(trait_did, _) => {
+            method_trait(trait_did, _, _) => {
                 self.report_trait_candidate(idx, trait_did)
             }
         }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index c04e1c2515c..0b80c0cb3c6 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -925,10 +925,15 @@ impl FnCtxt {
     pub fn region_var_if_parameterized(&self,
                                        rp: Option<ty::region_variance>,
                                        span: span)
-                                       -> Option<ty::Region> {
-        rp.map(
-            |_| self.infcx().next_region_var(
-                infer::BoundRegionInTypeOrImpl(span)))
+                                       -> OptVec<ty::Region> {
+        match rp {
+            None => opt_vec::Empty,
+            Some(_) => {
+                opt_vec::with(
+                    self.infcx().next_region_var(
+                        infer::BoundRegionInTypeOrImpl(span)))
+            }
+        }
     }
 
     pub fn type_error_message(&self,
@@ -1111,15 +1116,15 @@ pub fn impl_self_ty(vcx: &VtableContext,
         (ity.generics.type_param_defs.len(), ity.generics.region_param, ity.ty)
     };
 
-    let self_r = if region_param.is_some() {
-        Some(vcx.infcx.next_region_var(
+    let regions = ty::NonerasedRegions(if region_param.is_some() {
+        opt_vec::with(vcx.infcx.next_region_var(
             infer::BoundRegionInTypeOrImpl(location_info.span)))
     } else {
-        None
-    };
+        opt_vec::Empty
+    });
     let tps = vcx.infcx.next_ty_vars(n_tps);
 
-    let substs = substs { self_r: self_r, self_ty: None, tps: tps };
+    let substs = substs {regions: regions, self_ty: None, tps: tps};
     let substd_ty = ty::subst(tcx, &substs, raw_ty);
 
     ty_param_substs_and_ty { substs: substs, ty: substd_ty }
@@ -1986,7 +1991,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                         bound_self_region(region_parameterized);
 
                     raw_type = ty::mk_struct(tcx, class_id, substs {
-                        self_r: self_region,
+                        regions: ty::NonerasedRegions(self_region),
                         self_ty: None,
                         tps: ty::ty_params_to_tys(
                             tcx,
@@ -2006,11 +2011,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         }
 
         // Generate the struct type.
-        let self_region =
+        let regions =
             fcx.region_var_if_parameterized(region_parameterized, span);
         let type_parameters = fcx.infcx().next_ty_vars(type_parameter_count);
         let substitutions = substs {
-            self_r: self_region,
+            regions: ty::NonerasedRegions(regions),
             self_ty: None,
             tps: type_parameters
         };
@@ -2070,11 +2075,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
 
                     type_parameter_count = generics.ty_params.len();
 
-                    let self_region =
-                        bound_self_region(region_parameterized);
+                    let regions = bound_self_region(region_parameterized);
 
                     raw_type = ty::mk_enum(tcx, enum_id, substs {
-                        self_r: self_region,
+                        regions: ty::NonerasedRegions(regions),
                         self_ty: None,
                         tps: ty::ty_params_to_tys(
                             tcx,
@@ -2094,11 +2098,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         }
 
         // Generate the enum type.
-        let self_region =
+        let regions =
             fcx.region_var_if_parameterized(region_parameterized, span);
         let type_parameters = fcx.infcx().next_ty_vars(type_parameter_count);
         let substitutions = substs {
-            self_r: self_region,
+            regions: ty::NonerasedRegions(regions),
             self_ty: None,
             tps: type_parameters
         };
@@ -3139,8 +3143,8 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
 
         let rty = ty::node_id_to_type(ccx.tcx, id);
         let mut variants: ~[@ty::VariantInfo] = ~[];
-        let mut disr_vals: ~[int] = ~[];
-        let mut prev_disr_val: Option<int> = None;
+        let mut disr_vals: ~[uint] = ~[];
+        let mut prev_disr_val: Option<uint> = None;
 
         for vs.iter().advance |v| {
 
@@ -3155,15 +3159,16 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
                 Some(e) => {
                     debug!("disr expr, checking %s", pprust::expr_to_str(e, ccx.tcx.sess.intr()));
 
-                    let declty = ty::mk_int();
                     let fcx = blank_fn_ctxt(ccx, rty, e.id);
+                    let declty = ty::mk_int_var(ccx.tcx, fcx.infcx().next_int_var_id());
                     check_const_with_ty(fcx, e.span, e, declty);
                     // check_expr (from check_const pass) doesn't guarantee
                     // that the expression is in an form that eval_const_expr can
                     // handle, so we may still get an internal compiler error
 
                     match const_eval::eval_const_expr_partial(&ccx.tcx, e) {
-                        Ok(const_eval::const_int(val)) => current_disr_val = val as int,
+                        Ok(const_eval::const_int(val)) => current_disr_val = val as uint,
+                        Ok(const_eval::const_uint(val)) => current_disr_val = val as uint,
                         Ok(_) => {
                             ccx.tcx.sess.span_err(e.span, "expected signed integer constant");
                         }
@@ -3309,22 +3314,23 @@ 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 self_r = match pth.rp {
-      Some(_) => { // user supplied a lifetime parameter...
-        match tpt.generics.region_param {
-          None => { // ...but the type is not lifetime parameterized!
-            fcx.ccx.tcx.sess.span_err
-                (span, "this item is not region-parameterized");
-            None
-          }
-          Some(_) => { // ...and the type is lifetime parameterized, ok.
-            Some(ast_region_to_region(fcx, fcx, span, &pth.rp))
-          }
+    let regions = match pth.rp {
+        Some(_) => { // user supplied a lifetime parameter...
+            match tpt.generics.region_param {
+                None => { // ...but the type is not lifetime parameterized!
+                    fcx.ccx.tcx.sess.span_err
+                        (span, "this item is not region-parameterized");
+                    opt_vec::Empty
+                }
+                Some(_) => { // ...and the type is lifetime parameterized, ok.
+                    opt_vec::with(
+                        ast_region_to_region(fcx, fcx, span, &pth.rp))
+                }
+            }
+        }
+        None => { // no lifetime parameter supplied, insert default
+            fcx.region_var_if_parameterized(tpt.generics.region_param, span)
         }
-      }
-      None => { // no lifetime parameter supplied, insert default
-        fcx.region_var_if_parameterized(tpt.generics.region_param, span)
-      }
     };
 
     // determine values for type parameters, using the values given by
@@ -3351,7 +3357,9 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
         pth.types.map(|aty| fcx.to_ty(aty))
     };
 
-    let substs = substs { self_r: self_r, 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 da09f79d031..5e77ac30f47 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -16,11 +16,11 @@ use middle::typeck::check::{structurally_resolved_type};
 use middle::typeck::infer::fixup_err_to_str;
 use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
 use middle::typeck::infer;
-use middle::typeck::{CrateCtxt, vtable_origin, vtable_res};
-use middle::typeck::{vtable_static, vtable_param, vtable_self};
+use middle::typeck::{CrateCtxt, vtable_origin, vtable_res, vtable_param_res};
+use middle::typeck::{vtable_static, vtable_param, impl_res};
+use middle::typeck::{param_numbered, param_self, param_index};
 use middle::subst::Subst;
 use util::common::indenter;
-use util::ppaux::tys_to_str;
 use util::ppaux;
 
 use std::hashmap::HashSet;
@@ -46,6 +46,16 @@ use syntax::visit;
 // *fully* resolved. (We could be less restrictive than that, but it
 // would require much more care, and this seems to work decently in
 // practice.)
+//
+// While resolution on a single type requires the type to be fully
+// resolved, when resolving a substitution against a list of bounds,
+// we do not require all of the types to be resolved in advance.
+// Furthermore, we process substitutions in reverse order, which
+// allows resolution on later parameters to give information on
+// earlier params referenced by the typeclass bounds.
+// It may be better to do something more clever, like processing fully
+// resolved types first.
+
 
 /// Location info records the span and ID of the expression or item that is
 /// responsible for this vtable instantiation. (This may not be an expression
@@ -84,42 +94,19 @@ fn lookup_vtables(vcx: &VtableContext,
            substs.repr(vcx.tcx()));
     let _i = indenter();
 
-    let tcx = vcx.tcx();
-    let mut result = ~[];
-    let mut i = 0u;
-    for substs.tps.iter().advance |ty| {
-        // ty is the value supplied for the type parameter A...
-        let mut param_result = ~[];
-
-        for ty::each_bound_trait_and_supertraits(
-            tcx, type_param_defs[i].bounds) |trait_ref|
-        {
-            // ...and here trait_ref is each bound that was declared on A,
-            // expressed in terms of the type parameters.
-
-            debug!("about to subst: %s, %s", trait_ref.repr(tcx), substs.repr(tcx));
-
-            // Substitute the values of the type parameters that may
-            // appear in the bound.
-            let trait_ref = trait_ref.subst(tcx, substs);
-
-            debug!("after subst: %s", trait_ref.repr(tcx));
-
-            match lookup_vtable(vcx, location_info, *ty, trait_ref, is_early) {
-                Some(vtable) => param_result.push(vtable),
-                None => {
-                    vcx.tcx().sess.span_fatal(
-                        location_info.span,
-                        fmt!("failed to find an implementation of \
-                              trait %s for %s",
-                             vcx.infcx.trait_ref_to_str(trait_ref),
-                             vcx.infcx.ty_to_str(*ty)));
-                }
-            }
-        }
-        result.push(@param_result);
-        i += 1u;
-    }
+
+    // We do this backwards for reasons discussed above.
+    assert_eq!(substs.tps.len(), type_param_defs.len());
+    let mut result =
+        substs.tps.rev_iter()
+        .zip(type_param_defs.rev_iter())
+        .transform(|(ty, def)|
+                   lookup_vtables_for_param(vcx, location_info, Some(substs),
+                                            &*def.bounds, *ty, is_early))
+        .to_owned_vec();
+    result.reverse();
+
+    assert_eq!(substs.tps.len(), result.len());
     debug!("lookup_vtables result(\
             location_info=%?, \
             type_param_defs=%s, \
@@ -132,25 +119,58 @@ fn lookup_vtables(vcx: &VtableContext,
     @result
 }
 
-fn fixup_substs(vcx: &VtableContext,
-                location_info: &LocationInfo,
-                id: ast::def_id,
-                substs: ty::substs,
-                is_early: bool)
-                -> Option<ty::substs> {
+fn lookup_vtables_for_param(vcx: &VtableContext,
+                            location_info: &LocationInfo,
+                            // None for substs means the identity
+                            substs: Option<&ty::substs>,
+                            type_param_bounds: &ty::ParamBounds,
+                            ty: ty::t,
+                            is_early: bool) -> vtable_param_res {
     let tcx = vcx.tcx();
-    // use a dummy type just to package up the substs that need fixing up
-    let t = ty::mk_trait(tcx,
-                         id, substs,
-                         ty::RegionTraitStore(ty::re_static),
-                         ast::m_imm,
-                         ty::EmptyBuiltinBounds());
-    do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
-        match ty::get(*t_f).sty {
-          ty::ty_trait(_, ref substs_f, _, _, _) => (*substs_f).clone(),
-          _ => fail!("t_f should be a trait")
+
+    // ty is the value supplied for the type parameter A...
+    let mut param_result = ~[];
+
+    for ty::each_bound_trait_and_supertraits(
+        tcx, type_param_bounds.trait_bounds) |trait_ref|
+    {
+        // ...and here trait_ref is each bound that was declared on A,
+        // expressed in terms of the type parameters.
+
+        // Substitute the values of the type parameters that may
+        // appear in the bound.
+        let trait_ref = substs.map_default(trait_ref, |substs| {
+            debug!("about to subst: %s, %s",
+                   trait_ref.repr(tcx), substs.repr(tcx));
+            trait_ref.subst(tcx, *substs)
+        });
+
+        debug!("after subst: %s", trait_ref.repr(tcx));
+
+        match lookup_vtable(vcx, location_info, ty, trait_ref, is_early) {
+            Some(vtable) => param_result.push(vtable),
+            None => {
+                vcx.tcx().sess.span_fatal(
+                    location_info.span,
+                    fmt!("failed to find an implementation of \
+                          trait %s for %s",
+                         vcx.infcx.trait_ref_to_str(trait_ref),
+                         vcx.infcx.ty_to_str(ty)));
+            }
         }
     }
+
+    debug!("lookup_vtables_for_param result(\
+            location_info=%?, \
+            type_param_bounds=%s, \
+            ty=%s, \
+            result=%s)",
+           location_info,
+           type_param_bounds.repr(vcx.tcx()),
+           ty.repr(vcx.tcx()),
+           param_result.repr(vcx.tcx()));
+
+    return @param_result;
 }
 
 fn relate_trait_refs(vcx: &VtableContext,
@@ -173,10 +193,15 @@ fn relate_trait_refs(vcx: &VtableContext,
     {
         result::Ok(()) => {} // Ok.
         result::Err(ref err) => {
+            // There is an error, but we need to do some work to make
+            // the message good.
+            // Resolve any type vars in the trait refs
             let r_act_trait_ref =
                 vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(act_trait_ref);
             let r_exp_trait_ref =
                 vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(exp_trait_ref);
+            // Only print the message if there aren't any previous type errors
+            // inside the types.
             if !ty::trait_ref_contains_error(&r_act_trait_ref) &&
                 !ty::trait_ref_contains_error(&r_exp_trait_ref)
             {
@@ -192,8 +217,7 @@ fn relate_trait_refs(vcx: &VtableContext,
     }
 }
 
-// Look up the vtable to use when treating an item of type `t` as if it has
-// type `trait_ty`
+// Look up the vtable implementing the trait `trait_ref` at type `t`
 fn lookup_vtable(vcx: &VtableContext,
                  location_info: &LocationInfo,
                  ty: ty::t,
@@ -216,220 +240,247 @@ fn lookup_vtable(vcx: &VtableContext,
             // The type has unconstrained type variables in it, so we can't
             // do early resolution on it. Return some completely bogus vtable
             // information: we aren't storing it anyways.
-            return Some(vtable_param(0, 0));
+            return Some(vtable_param(param_self, 0));
         }
     };
 
-    match ty::get(ty).sty {
+    // If the type is self or a param, we look at the trait/supertrait
+    // bounds to see if they include the trait we are looking for.
+    let vtable_opt = match ty::get(ty).sty {
         ty::ty_param(param_ty {idx: n, def_id: did}) => {
-            let mut n_bound = 0;
             let type_param_def = tcx.ty_param_defs.get(&did.node);
-            for ty::each_bound_trait_and_supertraits(
-                tcx, type_param_def.bounds) |bound_trait_ref|
-            {
-                debug!("checking bounds trait %s", bound_trait_ref.repr(vcx.tcx()));
-
-                if bound_trait_ref.def_id == trait_ref.def_id {
-                    relate_trait_refs(vcx,
-                                      location_info,
-                                      bound_trait_ref,
-                                      trait_ref);
-                    let vtable = vtable_param(n, n_bound);
-                    debug!("found param vtable: %?",
-                           vtable);
-                    return Some(vtable);
-                }
-
-                n_bound += 1;
-            }
+            lookup_vtable_from_bounds(vcx, location_info,
+                                      type_param_def.bounds.trait_bounds,
+                                      param_numbered(n),
+                                      trait_ref)
         }
 
         ty::ty_self(trait_id) => {
-            debug!("trying to find %? vtable for type %?",
-                   trait_ref.def_id, trait_id);
+            let self_trait_ref = ty::lookup_trait_def(tcx, trait_id).trait_ref;
+            lookup_vtable_from_bounds(vcx, location_info,
+                                      &[self_trait_ref],
+                                      param_self,
+                                      trait_ref)
+        }
 
-            if trait_id == trait_ref.def_id {
-                let vtable = vtable_self(trait_id);
-                debug!("found self vtable: %?", vtable);
-                return Some(vtable);
-            }
+        // Default case just falls through
+        _ => None
+    };
+
+    if vtable_opt.is_some() { return vtable_opt; }
+
+    // If we aren't a self type or param, or it was, but we didn't find it,
+    // do a search.
+    return search_for_vtable(vcx, location_info,
+                             ty, trait_ref, is_early)
+}
+
+// Given a list of bounds on a type, search those bounds to see if any
+// of them are the vtable we are looking for.
+fn lookup_vtable_from_bounds(vcx: &VtableContext,
+                             location_info: &LocationInfo,
+                             bounds: &[@ty::TraitRef],
+                             param: param_index,
+                             trait_ref: @ty::TraitRef)
+    -> Option<vtable_origin> {
+    let tcx = vcx.tcx();
+
+    let mut n_bound = 0;
+    for ty::each_bound_trait_and_supertraits(tcx, bounds) |bound_trait_ref| {
+        debug!("checking bounds trait %s",
+               bound_trait_ref.repr(vcx.tcx()));
+
+        if bound_trait_ref.def_id == trait_ref.def_id {
+            relate_trait_refs(vcx,
+                              location_info,
+                              bound_trait_ref,
+                              trait_ref);
+            let vtable = vtable_param(param, n_bound);
+            debug!("found param vtable: %?",
+                   vtable);
+            return Some(vtable);
         }
 
-        _ => {
-            let mut found = ~[];
+        n_bound += 1;
+    }
 
-            let mut impls_seen = HashSet::new();
+    return None;
+}
 
-            match tcx.trait_impls.find(&trait_ref.def_id) {
-                None => {
-                    // Nothing found. Continue.
-                }
-                Some(implementations) => {
-                    // implementations is the list of all impls in scope for
-                    // trait_ref. (Usually, there's just one.)
-                    for implementations.iter().advance |im| {
-                        // im is one specific impl of trait_ref.
-
-                        // First, ensure we haven't processed this impl yet.
-                        if impls_seen.contains(&im.did) {
-                            loop;
-                        }
-                        impls_seen.insert(im.did);
-
-                        // ty::impl_traits gives us the trait im implements,
-                        // if there is one (there's either zero or one).
-                        //
-                        // If foo implements a trait t, and if t is the
-                        // same trait as trait_ref, we need to
-                        // unify it with trait_ref in order to get all
-                        // the ty vars sorted out.
-                        let r = ty::impl_trait_ref(tcx, im.did);
-                        for r.iter().advance |&of_trait_ref| {
-                            if of_trait_ref.def_id != trait_ref.def_id { loop; }
-
-                            // At this point, we know that of_trait_ref is
-                            // the same trait as trait_ref, but
-                            // possibly applied to different substs.
-                            //
-                            // Next, we check whether the "for" ty in
-                            // the impl is compatible with the type
-                            // that we're casting to a trait. That is,
-                            // if im is:
-                            //
-                            // impl<T> self_ty<T>: some_trait<T> { ... }
-                            //
-                            // we check whether self_ty<T> is the type
-                            // of the thing that we're trying to cast
-                            // to some_trait.  If not, then we try the next
-                            // impl.
-                            //
-                            // FIXME(#5781) this should be mk_eqty not mk_subty
-                            let ty::ty_param_substs_and_ty {
-                                substs: substs,
-                                ty: for_ty
-                            } = impl_self_ty(vcx, location_info, im.did);
-                            match infer::mk_subty(vcx.infcx,
-                                                  false,
-                                                  infer::RelateSelfType(
-                                                      location_info.span),
-                                                  ty,
-                                                  for_ty) {
-                                result::Err(_) => loop,
-                                result::Ok(()) => ()
-                            }
-
-                            // Now, in the previous example, for_ty is
-                            // bound to the type self_ty, and substs
-                            // is bound to [T].
-                            debug!("The self ty is %s and its substs are %s",
-                                   vcx.infcx.ty_to_str(for_ty),
-                                   tys_to_str(vcx.tcx(), substs.tps));
-
-                            // Next, we unify trait_ref -- the type
-                            // that we want to cast to -- with of_trait_ref
-                            // -- the trait that im implements. At
-                            // this point, we require that they be
-                            // unifiable with each other -- that's
-                            // what relate_trait_refs does.
-                            //
-                            // For example, in the above example,
-                            // of_trait_ref would be some_trait<T>, so we
-                            // would be unifying trait_ref<U> (for some
-                            // value of U) with some_trait<T>. This
-                            // would fail if T and U weren't
-                            // compatible.
-
-                            debug!("(checking vtable) @2 relating trait \
-                                    ty %s to of_trait_ref %s",
-                                   vcx.infcx.trait_ref_to_str(trait_ref),
-                                   vcx.infcx.trait_ref_to_str(of_trait_ref));
-
-                            let of_trait_ref = of_trait_ref.subst(tcx, &substs);
-                            relate_trait_refs(
-                                vcx, location_info,
-                                of_trait_ref, trait_ref);
-
-                            // Recall that trait_ref -- the trait type
-                            // we're casting to -- is the trait with
-                            // id trait_ref.def_id applied to the substs
-                            // trait_ref.substs. Now we extract out the
-                            // types themselves from trait_ref.substs.
-
-                            // Recall that substs is the impl self
-                            // type's list of substitutions. That is,
-                            // if this is an impl of some trait for
-                            // foo<T, U>, then substs is [T,
-                            // U]. substs might contain type
-                            // variables, so we call fixup_substs to
-                            // resolve them.
-
-                            let substs_f = match fixup_substs(vcx,
-                                                              location_info,
-                                                              trait_ref.def_id,
-                                                              substs,
-                                                              is_early) {
-                                Some(ref substs) => (*substs).clone(),
-                                None => {
-                                    assert!(is_early);
-                                    // Bail out with a bogus answer
-                                    return Some(vtable_param(0, 0));
-                                }
-                            };
-
-                            debug!("The fixed-up substs are %s - \
-                                    they will be unified with the bounds for \
-                                    the target ty, %s",
-                                   tys_to_str(vcx.tcx(), substs_f.tps),
-                                   vcx.infcx.trait_ref_to_str(trait_ref));
-
-                            // Next, we unify the fixed-up
-                            // substitutions for the impl self ty with
-                            // the substitutions from the trait type
-                            // that we're trying to cast
-                            // to. connect_trait_tps requires these
-                            // lists of types to unify pairwise.
-
-                            let im_generics =
-                                ty::lookup_item_type(tcx, im.did).generics;
-                            connect_trait_tps(vcx,
-                                              location_info,
-                                              &substs_f,
-                                              trait_ref,
-                                              im.did);
-                            let subres = lookup_vtables(
-                                vcx, location_info,
-                                *im_generics.type_param_defs, &substs_f,
-                                is_early);
-
-                            // Finally, we register that we found a
-                            // matching impl, and record the def ID of
-                            // the impl as well as the resolved list
-                            // of type substitutions for the target
-                            // trait.
-                            found.push(vtable_static(im.did,
-                                                     substs_f.tps.clone(),
-                                                     subres));
-                        }
-                    }
-                }
+fn search_for_vtable(vcx: &VtableContext,
+                     location_info: &LocationInfo,
+                     ty: ty::t,
+                     trait_ref: @ty::TraitRef,
+                     is_early: bool)
+    -> Option<vtable_origin>
+{
+    let tcx = vcx.tcx();
+
+    let mut found = ~[];
+    let mut impls_seen = HashSet::new();
+
+    // XXX: this is a bad way to do this, since we do
+    // pointless allocations.
+    let impls = tcx.trait_impls.find(&trait_ref.def_id)
+        .map_default(@mut ~[], |x| **x);
+    // impls is the list of all impls in scope for trait_ref.
+    for impls.iter().advance |im| {
+        // im is one specific impl of trait_ref.
+
+        // First, ensure we haven't processed this impl yet.
+        if impls_seen.contains(&im.did) {
+            loop;
+        }
+        impls_seen.insert(im.did);
+
+        // ty::impl_traits gives us the trait im implements.
+        //
+        // If foo implements a trait t, and if t is the same trait as
+        // trait_ref, we need to unify it with trait_ref in order to
+        // get all the ty vars sorted out.
+        let r = ty::impl_trait_ref(tcx, im.did);
+        let of_trait_ref = r.expect("trait_ref missing on trait impl");
+        if of_trait_ref.def_id != trait_ref.def_id { loop; }
+
+        // At this point, we know that of_trait_ref is the same trait
+        // as trait_ref, but possibly applied to different substs.
+        //
+        // Next, we check whether the "for" ty in the impl is
+        // compatible with the type that we're casting to a
+        // trait. That is, if im is:
+        //
+        // impl<T> some_trait<T> for self_ty<T> { ... }
+        //
+        // we check whether self_ty<T> is the type of the thing that
+        // we're trying to cast to some_trait.  If not, then we try
+        // the next impl.
+        //
+        // XXX: document a bit more what this means
+        //
+        // FIXME(#5781) this should be mk_eqty not mk_subty
+        let ty::ty_param_substs_and_ty {
+            substs: substs,
+            ty: for_ty
+        } = impl_self_ty(vcx, location_info, im.did);
+        match infer::mk_subty(vcx.infcx,
+                              false,
+                              infer::RelateSelfType(
+                                  location_info.span),
+                              ty,
+                              for_ty) {
+            result::Err(_) => loop,
+            result::Ok(()) => ()
+        }
+
+        // Now, in the previous example, for_ty is bound to
+        // the type self_ty, and substs is bound to [T].
+        debug!("The self ty is %s and its substs are %s",
+               vcx.infcx.ty_to_str(for_ty),
+               vcx.infcx.tys_to_str(substs.tps));
+
+        // Next, we unify trait_ref -- the type that we want to cast
+        // to -- with of_trait_ref -- the trait that im implements. At
+        // this point, we require that they be unifiable with each
+        // other -- that's what relate_trait_refs does.
+        //
+        // For example, in the above example, of_trait_ref would be
+        // some_trait<T>, so we would be unifying trait_ref<U> (for
+        // some value of U) with some_trait<T>. This would fail if T
+        // and U weren't compatible.
+
+        debug!("(checking vtable) @2 relating trait \
+                ty %s to of_trait_ref %s",
+               vcx.infcx.trait_ref_to_str(trait_ref),
+               vcx.infcx.trait_ref_to_str(of_trait_ref));
+
+        let of_trait_ref = of_trait_ref.subst(tcx, &substs);
+        relate_trait_refs(vcx, location_info, of_trait_ref, trait_ref);
+
+
+        // Recall that trait_ref -- the trait type we're casting to --
+        // is the trait with id trait_ref.def_id applied to the substs
+        // trait_ref.substs.
+
+        // Resolve any sub bounds. Note that there still may be free
+        // type variables in substs. This might still be OK: the
+        // process of looking up bounds might constrain some of them.
+        let im_generics =
+            ty::lookup_item_type(tcx, im.did).generics;
+        let subres = lookup_vtables(vcx, location_info,
+                                    *im_generics.type_param_defs, &substs,
+                                    is_early);
+
+
+        // substs might contain type variables, so we call
+        // fixup_substs to resolve them.
+        let substs_f = match fixup_substs(vcx,
+                                          location_info,
+                                          trait_ref.def_id,
+                                          substs,
+                                          is_early) {
+            Some(ref substs) => (*substs).clone(),
+            None => {
+                assert!(is_early);
+                // Bail out with a bogus answer
+                return Some(vtable_param(param_self, 0));
             }
+        };
+
+        debug!("The fixed-up substs are %s - \
+                they will be unified with the bounds for \
+                the target ty, %s",
+               vcx.infcx.tys_to_str(substs_f.tps),
+               vcx.infcx.trait_ref_to_str(trait_ref));
+
+        // Next, we unify the fixed-up substitutions for the impl self
+        // ty with the substitutions from the trait type that we're
+        // trying to cast to. connect_trait_tps requires these lists
+        // of types to unify pairwise.
+        // I am a little confused about this, since it seems to be
+        // very similar to the relate_trait_refs we already do,
+        // but problems crop up if it is removed, so... -sully
+        connect_trait_tps(vcx, location_info, &substs_f, trait_ref, im.did);
+
+        // Finally, we register that we found a matching impl, and
+        // record the def ID of the impl as well as the resolved list
+        // of type substitutions for the target trait.
+        found.push(vtable_static(im.did, substs_f.tps.clone(), subres));
+    }
 
-            match found.len() {
-                0 => { /* fallthrough */ }
-                1 => return Some(found[0].clone()),
-                _ => {
-                    if !is_early {
-                        vcx.tcx().sess.span_err(
-                            location_info.span,
-                            "multiple applicable methods in scope");
-                    }
-                    return Some(found[0].clone());
-                }
+    match found.len() {
+        0 => { return None }
+        1 => return Some(found[0].clone()),
+        _ => {
+            if !is_early {
+                vcx.tcx().sess.span_err(
+                    location_info.span,
+                    "multiple applicable methods in scope");
             }
+            return Some(found[0].clone());
         }
     }
+}
 
-    return None;
+
+fn fixup_substs(vcx: &VtableContext,
+                location_info: &LocationInfo,
+                id: ast::def_id,
+                substs: ty::substs,
+                is_early: bool)
+                -> Option<ty::substs> {
+    let tcx = vcx.tcx();
+    // use a dummy type just to package up the substs that need fixing up
+    let t = ty::mk_trait(tcx,
+                         id, substs,
+                         ty::RegionTraitStore(ty::re_static),
+                         ast::m_imm,
+                         ty::EmptyBuiltinBounds());
+    do fixup_ty(vcx, location_info, t, is_early).map |t_f| {
+        match ty::get(*t_f).sty {
+          ty::ty_trait(_, ref substs_f, _, _, _) => (*substs_f).clone(),
+          _ => fail!("t_f should be a trait")
+        }
+    }
 }
 
 fn fixup_ty(vcx: &VtableContext,
@@ -590,7 +641,7 @@ pub fn early_resolve_expr(ex: @ast::expr,
                               def_id: target_def_id,
                               substs: ty::substs {
                                   tps: target_substs.tps.clone(),
-                                  self_r: target_substs.self_r,
+                                  regions: target_substs.regions.clone(),
                                   self_ty: Some(mt.ty)
                               }
                           };
@@ -682,16 +733,39 @@ pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
         Some(trait_ref) => {
             let infcx = infer::new_infer_ctxt(ccx.tcx);
             let vcx = VtableContext { ccx: ccx, infcx: infcx };
-            let trait_def = ty::lookup_trait_def(ccx.tcx, trait_ref.def_id);
+            let loc_info = location_info_for_item(impl_item);
 
+            // First, check that the impl implements any trait bounds
+            // on the trait.
+            let trait_def = ty::lookup_trait_def(ccx.tcx, trait_ref.def_id);
             let vtbls = lookup_vtables(&vcx,
-                                       &location_info_for_item(impl_item),
+                                       &loc_info,
                                        *trait_def.generics.type_param_defs,
                                        &trait_ref.substs,
                                        false);
 
-            // FIXME(#7450): Doesn't work cross crate
-            ccx.vtable_map.insert(impl_item.id, vtbls);
+            // Now, locate the vtable for the impl itself. The real
+            // purpose of this is to check for supertrait impls,
+            // but that falls out of doing this.
+            let param_bounds = ty::ParamBounds {
+                builtin_bounds: ty::EmptyBuiltinBounds(),
+                trait_bounds: ~[trait_ref]
+            };
+            let t = ty::node_id_to_type(ccx.tcx, impl_item.id);
+            debug!("=== Doing a self lookup now.");
+            // Right now, we don't have any place to store this.
+            // We will need to make one so we can use this information
+            // for compiling default methods that refer to supertraits.
+            let self_vtable_res =
+                lookup_vtables_for_param(&vcx, &loc_info, None,
+                                         &param_bounds, t, false);
+
+
+            let res = impl_res {
+                trait_vtables: vtbls,
+                self_vtables: self_vtable_res
+            };
+            ccx.tcx.impl_vtables.insert(def_id, res);
         }
     }
 }
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 4d437d83f2a..a7319d4b008 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -20,7 +20,7 @@ use middle::typeck::infer::{force_all, resolve_all, resolve_region};
 use middle::typeck::infer::resolve_type;
 use middle::typeck::infer;
 use middle::typeck::{vtable_res, vtable_origin};
-use middle::typeck::{vtable_static, vtable_param, vtable_self};
+use middle::typeck::{vtable_static, vtable_param};
 use middle::typeck::method_map_entry;
 use middle::typeck::write_substs_to_tcx;
 use middle::typeck::write_ty_to_tcx;
@@ -109,9 +109,6 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) {
             &vtable_param(n, b) => {
                 vtable_param(n, b)
             }
-            &vtable_self(def_id) => {
-                vtable_self(def_id)
-            }
         }
     }
 }
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index 84a2627c87c..4298f043e93 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -45,6 +45,7 @@ use syntax::ast_map;
 use syntax::ast_util::{def_id_of_def, local_def};
 use syntax::codemap::{span, dummy_sp};
 use syntax::parse;
+use syntax::opt_vec;
 use syntax::visit::{default_simple_visitor, default_visitor};
 use syntax::visit::{mk_simple_visitor, mk_vt, visit_crate, visit_item};
 use syntax::visit::{Visitor, SimpleVisitor};
@@ -436,16 +437,20 @@ impl CoherenceChecker {
     pub fn universally_quantify_polytype(&self,
                                          polytype: ty_param_bounds_and_ty)
                                          -> UniversalQuantificationResult {
-        let self_region =
-            polytype.generics.region_param.map(
-                |_| self.inference_context.next_region_var(
-                    infer::BoundRegionInCoherence));
+        let regions = match polytype.generics.region_param {
+            None => opt_vec::Empty,
+            Some(_) => {
+                opt_vec::with(
+                    self.inference_context.next_region_var(
+                        infer::BoundRegionInCoherence))
+            }
+        };
 
         let bounds_count = polytype.generics.type_param_defs.len();
         let type_parameters = self.inference_context.next_ty_vars(bounds_count);
 
         let substitutions = substs {
-            self_r: self_region,
+            regions: ty::NonerasedRegions(regions),
             self_ty: None,
             tps: type_parameters
         };
@@ -453,13 +458,9 @@ impl CoherenceChecker {
                              &substitutions,
                              polytype.ty);
 
-        // Get our type parameters back.
-        let substs { self_r: _, self_ty: _, tps: type_parameters } =
-            substitutions;
-
         UniversalQuantificationResult {
             monotype: monotype,
-            type_variables: type_parameters,
+            type_variables: substitutions.tps,
             type_param_defs: polytype.generics.type_param_defs
         }
     }
@@ -845,7 +846,7 @@ pub fn make_substs_for_receiver_types(tcx: ty::ctxt,
     });
 
     return ty::substs {
-        self_r: trait_ref.substs.self_r,
+        regions: trait_ref.substs.regions.clone(),
         self_ty: trait_ref.substs.self_ty,
         tps: combined_tps
     };
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 3db881dac1a..98b4de9d719 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -301,7 +301,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
         //     Self => D'
         //     D,E,F => E',F',G'
         let substs = substs {
-            self_r: None,
+            regions: ty::NonerasedRegions(opt_vec::Empty),
             self_ty: Some(self_param),
             tps: non_shifted_trait_tps + shifted_method_tps
         };
@@ -622,7 +622,7 @@ pub fn compare_impl_method(tcx: ty::ctxt,
         let trait_tps = trait_substs.tps.map(
             |t| replace_bound_self(tcx, *t, dummy_self_r));
         let substs = substs {
-            self_r: Some(dummy_self_r),
+            regions: ty::NonerasedRegions(opt_vec::with(dummy_self_r)),
             self_ty: Some(self_ty),
             tps: vec::append(trait_tps, dummy_tps)
         };
@@ -1268,6 +1268,8 @@ pub fn mk_item_substs(ccx: &CrateCtxt,
         i += 1u;
         t
     });
-    let self_r = rscope::bound_self_region(rp);
-    (ty_generics, substs {self_r: self_r, self_ty: self_ty, tps: params})
+    let regions = rscope::bound_self_region(rp);
+    (ty_generics, substs {regions: ty::NonerasedRegions(regions),
+                          self_ty: self_ty,
+                          tps: params})
 }
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 65fbd080561..b1492cac16e 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -197,56 +197,67 @@ pub fn super_substs<C:Combine>(
     this: &C, generics: &ty::Generics,
     a: &ty::substs, b: &ty::substs) -> cres<ty::substs> {
 
-    fn relate_region_param<C:Combine>(
+    fn relate_region_params<C:Combine>(
         this: &C,
         generics: &ty::Generics,
-        a: Option<ty::Region>,
-        b: Option<ty::Region>)
-        -> cres<Option<ty::Region>>
+        a: &ty::RegionSubsts,
+        b: &ty::RegionSubsts)
+        -> cres<ty::RegionSubsts>
     {
-        match (&generics.region_param, &a, &b) {
-          (&None, &None, &None) => {
-            Ok(None)
-          }
-          (&Some(ty::rv_invariant), &Some(a), &Some(b)) => {
-            do eq_regions(this, a, b).then {
-                Ok(Some(a))
-            }
-          }
-          (&Some(ty::rv_covariant), &Some(a), &Some(b)) => {
-            do this.regions(a, b).chain |r| {
-                Ok(Some(r))
+        match (a, b) {
+            (&ty::ErasedRegions, _) |
+            (_, &ty::ErasedRegions) => {
+                Ok(ty::ErasedRegions)
             }
-          }
-          (&Some(ty::rv_contravariant), &Some(a), &Some(b)) => {
-            do this.contraregions(a, b).chain |r| {
-                Ok(Some(r))
+
+            (&ty::NonerasedRegions(ref a_rs),
+             &ty::NonerasedRegions(ref b_rs)) => {
+                match generics.region_param {
+                    None => {
+                        assert!(a_rs.is_empty());
+                        assert!(b_rs.is_empty());
+                        Ok(ty::NonerasedRegions(opt_vec::Empty))
+                    }
+
+                    Some(variance) => {
+                        assert_eq!(a_rs.len(), 1);
+                        assert_eq!(b_rs.len(), 1);
+                        let a_r = *a_rs.get(0);
+                        let b_r = *b_rs.get(0);
+
+                        match variance {
+                            ty::rv_invariant => {
+                                do eq_regions(this, a_r, b_r).then {
+                                    Ok(ty::NonerasedRegions(opt_vec::with(a_r)))
+                                }
+                            }
+
+                            ty::rv_covariant => {
+                                do this.regions(a_r, b_r).chain |r| {
+                                    Ok(ty::NonerasedRegions(opt_vec::with(r)))
+                                }
+                            }
+
+                            ty::rv_contravariant => {
+                                do this.contraregions(a_r, b_r).chain |r| {
+                                    Ok(ty::NonerasedRegions(opt_vec::with(r)))
+                                }
+                            }
+                        }
+                    }
+                }
             }
-          }
-          (_, _, _) => {
-            // If these two substitutions are for the same type (and
-            // they should be), then the type should either
-            // consistently have a region parameter or not have a
-            // region parameter, and that should match with the
-            // polytype.
-            this.infcx().tcx.sess.bug(
-                fmt!("substitution a had opt_region %s and \
-                      b had opt_region %s with variance %?",
-                      a.inf_str(this.infcx()),
-                      b.inf_str(this.infcx()),
-                     generics.region_param));
-          }
         }
     }
 
     do this.tps(a.tps, b.tps).chain |tps| {
         do this.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
-            do relate_region_param(this,
-                                   generics,
-                                   a.self_r,
-                                   b.self_r).chain |self_r| {
+            do relate_region_params(this,
+                                    generics,
+                                    &a.regions,
+                                    &b.regions).chain |regions| {
                 Ok(substs {
-                    self_r: self_r,
+                    regions: regions,
                     self_ty: self_ty,
                     tps: tps.clone()
                 })
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index 1f0fb135762..eb32f4e59f0 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -653,6 +653,11 @@ impl InferCtxt {
                   self.resolve_type_vars_if_possible(t))
     }
 
+    pub fn tys_to_str(@mut self, ts: &[ty::t]) -> ~str {
+        let tstrs = ts.map(|t| self.ty_to_str(*t));
+        fmt!("(%s)", tstrs.connect(", "))
+    }
+
     pub fn trait_ref_to_str(@mut self, t: &ty::TraitRef) -> ~str {
         let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
         trait_ref_to_str(self.tcx, &t)
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 81b18e746b2..0ea00e15863 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -75,14 +75,14 @@ pub mod infer;
 pub mod collect;
 pub mod coherence;
 
+#[deriving(Clone, Encodable, Decodable, Eq, Ord)]
+pub enum param_index {
+    param_numbered(uint),
+    param_self
+}
+
 #[deriving(Clone, Encodable, Decodable)]
 pub enum method_origin {
-    // supertrait method invoked on "self" inside a default method
-    // first field is supertrait ID;
-    // second field is method index (relative to the *supertrait*
-    // method list)
-    method_super(ast::def_id, uint),
-
     // fully statically resolved method
     method_static(ast::def_id),
 
@@ -92,9 +92,6 @@ pub enum method_origin {
     // method invoked on a trait instance
     method_trait(ast::def_id, uint, ty::TraitStore),
 
-    // method invoked on "self" inside a default method
-    method_self(ast::def_id, uint)
-
 }
 
 // details for a method invoked with a receiver whose type is a type parameter
@@ -109,7 +106,7 @@ pub struct method_param {
 
     // index of the type parameter (from those that are in scope) that is
     // the type of the receiver
-    param_num: uint,
+    param_num: param_index,
 
     // index of the bound for this type parameter which specifies the trait
     bound_num: uint,
@@ -153,15 +150,10 @@ pub enum vtable_origin {
       fn foo<T:quux,baz,bar>(a: T) -- a's vtable would have a
       vtable_param origin
 
-      The first uint is the param number (identifying T in the example),
+      The first argument is the param index (identifying T in the example),
       and the second is the bound number (identifying baz)
      */
-    vtable_param(uint, uint),
-
-    /*
-     Dynamic vtable, comes from self.
-    */
-    vtable_self(ast::def_id)
+    vtable_param(param_index, uint),
 }
 
 impl Repr for vtable_origin {
@@ -178,15 +170,34 @@ impl Repr for vtable_origin {
             vtable_param(x, y) => {
                 fmt!("vtable_param(%?, %?)", x, y)
             }
-            vtable_self(def_id) => {
-                fmt!("vtable_self(%?)", def_id)
-            }
         }
     }
 }
 
 pub type vtable_map = @mut HashMap<ast::node_id, vtable_res>;
 
+
+// Information about the vtable resolutions for for a trait impl.
+// Mostly the information is important for implementing default
+// methods.
+#[deriving(Clone)]
+pub struct impl_res {
+    // resolutions for any bounded params on the trait definition
+    trait_vtables: vtable_res,
+    // resolutions for the trait /itself/ (and for supertraits)
+    self_vtables: vtable_param_res
+}
+
+impl Repr for impl_res {
+    fn repr(&self, tcx: ty::ctxt) -> ~str {
+        fmt!("impl_res {trait_vtables=%s, self_vtables=%s}",
+             self.trait_vtables.repr(tcx),
+             self.self_vtables.repr(tcx))
+    }
+}
+
+pub type impl_vtable_map = @mut HashMap<ast::def_id, impl_res>;
+
 pub struct CrateCtxt {
     // A mapping from method call sites to traits that have that method.
     trait_map: resolve::TraitMap,
diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs
index 2f319687f6c..94d30fd9a87 100644
--- a/src/librustc/middle/typeck/rscope.rs
+++ b/src/librustc/middle/typeck/rscope.rs
@@ -260,10 +260,10 @@ impl region_scope for type_rscope {
 }
 
 pub fn bound_self_region(rp: Option<ty::region_variance>)
-                      -> Option<ty::Region> {
+                      -> OptVec<ty::Region> {
     match rp {
-      Some(_) => Some(ty::re_bound(ty::br_self)),
-      None => None
+      Some(_) => opt_vec::with(ty::re_bound(ty::br_self)),
+      None => opt_vec::Empty
     }
 }
 
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 32ac5e72928..a8967e7a878 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -30,6 +30,8 @@ use syntax::codemap::span;
 use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::{ast, ast_util};
+use syntax::opt_vec;
+use syntax::opt_vec::OptVec;
 
 /// Produces a string suitable for debugging output.
 pub trait Repr {
@@ -451,12 +453,12 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
       ty_enum(did, ref substs) | ty_struct(did, ref substs) => {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path, cx.sess.intr());
-        parameterized(cx, base, substs.self_r, substs.tps)
+        parameterized(cx, base, &substs.regions, substs.tps)
       }
       ty_trait(did, ref substs, s, mutbl, ref bounds) => {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path, cx.sess.intr());
-        let ty = parameterized(cx, base, substs.self_r, substs.tps);
+        let ty = parameterized(cx, base, &substs.regions, substs.tps);
         let bound_sep = if bounds.is_empty() { "" } else { ":" };
         let bound_str = bounds.repr(cx);
         fmt!("%s%s%s%s%s", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty,
@@ -475,16 +477,18 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
 
 pub fn parameterized(cx: ctxt,
                      base: &str,
-                     self_r: Option<ty::Region>,
+                     regions: &ty::RegionSubsts,
                      tps: &[ty::t]) -> ~str {
 
     let mut strs = ~[];
-    match self_r {
-        None => (),
-        Some(r) => {
-            strs.push(region_to_str(cx, "", false, r))
+    match *regions {
+        ty::ErasedRegions => { }
+        ty::NonerasedRegions(ref regions) => {
+            for regions.iter().advance |&r| {
+                strs.push(region_to_str(cx, "", false, r))
+            }
         }
-    };
+    }
 
     for tps.iter().advance |t| {
         strs.push(ty_to_str(cx, *t))
@@ -534,6 +538,15 @@ impl<'self, T:Repr> Repr for &'self [T] {
     }
 }
 
+impl<T:Repr> Repr for OptVec<T> {
+    fn repr(&self, tcx: ctxt) -> ~str {
+        match *self {
+            opt_vec::Empty => ~"[]",
+            opt_vec::Vec(ref v) => repr_vec(tcx, *v)
+        }
+    }
+}
+
 // This is necessary to handle types like Option<~[T]>, for which
 // autoderef cannot convert the &[T] handler
 impl<T:Repr> Repr for ~[T] {
@@ -557,13 +570,22 @@ impl Repr for ty::t {
 
 impl Repr for ty::substs {
     fn repr(&self, tcx: ctxt) -> ~str {
-        fmt!("substs(self_r=%s, self_ty=%s, tps=%s)",
-             self.self_r.repr(tcx),
+        fmt!("substs(regions=%s, self_ty=%s, tps=%s)",
+             self.regions.repr(tcx),
              self.self_ty.repr(tcx),
              self.tps.repr(tcx))
     }
 }
 
+impl Repr for ty::RegionSubsts {
+    fn repr(&self, tcx: ctxt) -> ~str {
+        match *self {
+            ty::ErasedRegions => ~"erased",
+            ty::NonerasedRegions(ref regions) => regions.repr(tcx)
+        }
+    }
+}
+
 impl Repr for ty::ParamBounds {
     fn repr(&self, tcx: ctxt) -> ~str {
         let mut res = ~[];
@@ -715,10 +737,6 @@ impl Repr for typeck::method_map_entry {
 impl Repr for typeck::method_origin {
     fn repr(&self, tcx: ctxt) -> ~str {
         match self {
-            &typeck::method_super(def_id, n) => {
-                fmt!("method_super(%s, %?)",
-                     def_id.repr(tcx), n)
-            }
             &typeck::method_static(def_id) => {
                 fmt!("method_static(%s)", def_id.repr(tcx))
             }
@@ -729,9 +747,6 @@ impl Repr for typeck::method_origin {
                 fmt!("method_trait(%s, %?, %s)", def_id.repr(tcx), n,
                      st.repr(tcx))
             }
-            &typeck::method_self(def_id, n) => {
-                fmt!("method_self(%s, %?)", def_id.repr(tcx), n)
-            }
         }
     }
 }
@@ -832,10 +847,9 @@ impl UserString for ty::TraitRef {
         if tcx.sess.verbose() && self.substs.self_ty.is_some() {
             let mut all_tps = self.substs.tps.clone();
             for self.substs.self_ty.iter().advance |&t| { all_tps.push(t); }
-            parameterized(tcx, base, self.substs.self_r, all_tps)
+            parameterized(tcx, base, &self.substs.regions, all_tps)
         } else {
-            parameterized(tcx, base, self.substs.self_r,
-                          self.substs.tps)
+            parameterized(tcx, base, &self.substs.regions, self.substs.tps)
         }
     }
 }
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 13354e61284..0b2519e6fb4 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -10,13 +10,13 @@
 
 //! Managed vectors
 
-use cast::transmute;
 use clone::Clone;
 use container::Container;
 use iterator::IteratorUtil;
 use option::Option;
 use sys;
 use uint;
+use unstable::raw::Repr;
 use vec::{ImmutableVector, OwnedVector};
 
 /// Code for dealing with @-vectors. This is pretty incomplete, and
@@ -26,8 +26,8 @@ use vec::{ImmutableVector, OwnedVector};
 #[inline]
 pub fn capacity<T>(v: @[T]) -> uint {
     unsafe {
-        let repr: **raw::VecRepr = transmute(&v);
-        (**repr).unboxed.alloc / sys::size_of::<T>()
+        let box = v.repr();
+        (*box).data.alloc / sys::size_of::<T>()
     }
 }
 
@@ -45,10 +45,10 @@ pub fn capacity<T>(v: @[T]) -> uint {
  */
 #[inline]
 pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
-    let mut vec: @[A] = @[];
+    let mut vec = @[];
     unsafe { raw::reserve(&mut vec, size); }
     builder(|x| unsafe { raw::push(&mut vec, x) });
-    return unsafe { transmute(vec) };
+    vec
 }
 
 /**
@@ -151,7 +151,7 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] {
         for v.consume_iter().advance |x| {
             raw::push(&mut av, x);
         }
-        transmute(av)
+        av
     }
 }
 
@@ -195,13 +195,9 @@ pub mod raw {
     use ptr;
     use sys;
     use uint;
-    use unstable::intrinsics;
     use unstable::intrinsics::{move_val_init, TyDesc};
-    use vec;
-    use vec::UnboxedVecRepr;
-
-    pub type VecRepr = vec::raw::VecRepr;
-    pub type SliceRepr = vec::raw::SliceRepr;
+    use unstable::intrinsics;
+    use unstable::raw::{Box, Vec};
 
     /**
      * Sets the length of a vector
@@ -211,9 +207,9 @@ pub mod raw {
      * the vector is actually the specified size.
      */
     #[inline]
-    pub unsafe fn set_len<T>(v: @[T], new_len: uint) {
-        let repr: **mut VecRepr = transmute(&v);
-        (**repr).unboxed.fill = new_len * sys::size_of::<T>();
+    pub unsafe fn set_len<T>(v: &mut @[T], new_len: uint) {
+        let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
+        (*repr).data.fill = new_len * sys::size_of::<T>();
     }
 
     /**
@@ -221,9 +217,11 @@ pub mod raw {
      */
     #[inline]
     pub unsafe fn push<T>(v: &mut @[T], initval: T) {
-        let repr: **VecRepr = transmute_copy(&v);
-        let fill = (**repr).unboxed.fill;
-        if (**repr).unboxed.alloc > fill {
+        let full = {
+            let repr: *Box<Vec<T>> = cast::transmute_copy(v);
+            (*repr).data.alloc > (*repr).data.fill
+        };
+        if full {
             push_fast(v, initval);
         } else {
             push_slow(v, initval);
@@ -232,16 +230,15 @@ pub mod raw {
 
     #[inline] // really pretty please
     unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
-        let repr: **mut VecRepr = ::cast::transmute(v);
-        let fill = (**repr).unboxed.fill;
-        (**repr).unboxed.fill += sys::size_of::<T>();
-        let p = &((**repr).unboxed.data);
-        let p = ptr::offset(p, fill) as *mut T;
+        let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
+        let amt = v.len();
+        (*repr).data.fill += sys::size_of::<T>();
+        let p = ptr::offset(&(*repr).data.data as *T, amt) as *mut T;
         move_val_init(&mut(*p), initval);
     }
 
     unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
-        reserve_at_least(&mut *v, v.len() + 1u);
+        reserve_at_least(v, v.len() + 1u);
         push_fast(v, initval);
     }
 
@@ -259,7 +256,7 @@ pub mod raw {
     pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
         // Only make the (slow) call into the runtime if we have to
         if capacity(*v) < n {
-            let ptr: *mut *mut VecRepr = transmute(v);
+            let ptr: *mut *mut Box<Vec<()>> = transmute(v);
             let ty = intrinsics::get_tydesc::<T>();
             // XXX transmute shouldn't be necessary
             let ty = cast::transmute(ty);
@@ -269,16 +266,14 @@ pub mod raw {
 
     // Implementation detail. Shouldn't be public
     #[allow(missing_doc)]
-    pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut VecRepr, n: uint) {
+    pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut Box<Vec<()>>, n: uint) {
 
         unsafe {
             let size_in_bytes = n * (*ty).size;
-            if size_in_bytes > (**ptr).unboxed.alloc {
-                let total_size = size_in_bytes + sys::size_of::<UnboxedVecRepr>();
-                // XXX: UnboxedVecRepr has an extra u8 at the end
-                let total_size = total_size - sys::size_of::<u8>();
-                (*ptr) = local_realloc(*ptr as *(), total_size) as *mut VecRepr;
-                (**ptr).unboxed.alloc = size_in_bytes;
+            if size_in_bytes > (**ptr).data.alloc {
+                let total_size = size_in_bytes + sys::size_of::<Vec<()>>();
+                (*ptr) = local_realloc(*ptr as *(), total_size) as *mut Box<Vec<()>>;
+                (**ptr).data.alloc = size_in_bytes;
             }
         }
 
diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs
index 126650981cd..eeaea6a2cff 100644
--- a/src/libstd/bool.rs
+++ b/src/libstd/bool.rs
@@ -24,6 +24,7 @@ Implementations of the following traits:
 * `Ord`
 * `TotalOrd`
 * `Eq`
+* `Zero`
 
 ## Various functions to compare `bool`s
 
@@ -36,14 +37,14 @@ Finally, some inquries into the nature of truth: `is_true` and `is_false`.
 
 */
 
-#[cfg(not(test))]
-use cmp::{Eq, Ord, TotalOrd, Ordering};
-#[cfg(not(test))]
-use ops::Not;
 use option::{None, Option, Some};
 use from_str::FromStr;
 use to_str::ToStr;
 
+#[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering};
+#[cfg(not(test))] use ops::Not;
+#[cfg(not(test))] use num::Zero;
+
 /**
 * Negation of a boolean value.
 *
@@ -330,6 +331,12 @@ impl Eq for bool {
     fn ne(&self, other: &bool) -> bool { (*self) != (*other) }
 }
 
+#[cfg(not(test))]
+impl Zero for bool {
+    fn zero() -> bool { false }
+    fn is_zero(&self) -> bool { *self == false }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs
index 86eec80ae6f..ee91d127909 100644
--- a/src/libstd/cast.rs
+++ b/src/libstd/cast.rs
@@ -133,6 +133,7 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
 #[cfg(test)]
 mod tests {
     use cast::{bump_box_refcount, transmute};
+    use unstable::raw;
 
     #[test]
     fn test_transmute_copy() {
@@ -156,10 +157,9 @@ mod tests {
 
     #[test]
     fn test_transmute() {
-        use managed::raw::BoxRepr;
         unsafe {
             let x = @100u8;
-            let x: *BoxRepr = transmute(x);
+            let x: *raw::Box<u8> = transmute(x);
             assert!((*x).data == 100);
             let _x: @int = transmute(x);
         }
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs
index 2ea10b09c8e..ed2b0e16818 100644
--- a/src/libstd/cleanup.rs
+++ b/src/libstd/cleanup.rs
@@ -12,9 +12,8 @@
 
 use libc::c_void;
 use ptr::{mut_null};
-use repr::BoxRepr;
-use cast::transmute;
 use unstable::intrinsics::TyDesc;
+use unstable::raw;
 
 type DropGlue<'self> = &'self fn(**TyDesc, *c_void);
 
@@ -31,27 +30,25 @@ struct AnnihilateStats {
 }
 
 unsafe fn each_live_alloc(read_next_before: bool,
-                          f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) -> bool {
+                          f: &fn(box: *mut raw::Box<()>, uniq: bool) -> bool) -> bool {
     //! Walks the internal list of allocations
 
     use managed;
     use rt::local_heap;
 
-    let box = local_heap::live_allocs();
-    let mut box: *mut BoxRepr = transmute(box);
+    let mut box = local_heap::live_allocs();
     while box != mut_null() {
-        let next_before = transmute((*box).header.next);
-        let uniq =
-            (*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE;
+        let next_before = (*box).next;
+        let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE;
 
-        if !f(box, uniq) {
+        if !f(box as *mut raw::Box<()>, uniq) {
             return false;
         }
 
         if read_next_before {
             box = next_before;
         } else {
-            box = transmute((*box).header.next);
+            box = (*box).next;
         }
     }
     return true;
@@ -102,7 +99,7 @@ pub unsafe fn annihilate() {
         if uniq {
             stats.n_unique_boxes += 1;
         } else {
-            (*box).header.ref_count = managed::raw::RC_IMMORTAL;
+            (*box).ref_count = managed::RC_IMMORTAL;
         }
     }
 
@@ -113,9 +110,9 @@ pub unsafe fn annihilate() {
     // callback, as the original value may have been freed.
     for each_live_alloc(false) |box, uniq| {
         if !uniq {
-            let tydesc: *TyDesc = transmute((*box).header.type_desc);
-            let data = transmute(&(*box).data);
-            ((*tydesc).drop_glue)(data);
+            let tydesc = (*box).type_desc;
+            let data = &(*box).data as *();
+            ((*tydesc).drop_glue)(data as *i8);
         }
     }
 
@@ -128,9 +125,9 @@ pub unsafe fn annihilate() {
     for each_live_alloc(true) |box, uniq| {
         if !uniq {
             stats.n_bytes_freed +=
-                (*((*box).header.type_desc)).size
-                + sys::size_of::<BoxRepr>();
-            local_free(transmute(box));
+                (*((*box).type_desc)).size
+                + sys::size_of::<raw::Box<()>>();
+            local_free(box as *i8);
         }
     }
 
diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs
index 8a13cab28c3..7991e1cb56e 100644
--- a/src/libstd/cmp.rs
+++ b/src/libstd/cmp.rs
@@ -21,7 +21,6 @@ and `Eq` to overload the `==` and `!=` operators.
 */
 
 #[allow(missing_doc)];
-#[allow(default_methods)]; // NOTE: Remove when allowed in stage0
 
 /**
 * Trait for values that can be compared for equality and inequality.
@@ -86,6 +85,12 @@ pub trait TotalOrd: TotalEq {
     fn cmp(&self, other: &Self) -> Ordering;
 }
 
+impl TotalEq for Ordering {
+    #[inline]
+    fn equals(&self, other: &Ordering) -> bool {
+        *self == *other
+    }
+}
 impl TotalOrd for Ordering {
     #[inline]
     fn cmp(&self, other: &Ordering) -> Ordering {
diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs
index 911fb5625e5..4feec26a2d9 100644
--- a/src/libstd/gc.rs
+++ b/src/libstd/gc.rs
@@ -74,14 +74,14 @@ pub mod rustrt {
 }
 
 unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U {
-    return cast::transmute(ptr::offset(ptr, count));
+    return ptr::offset(ptr, count) as *U;
 }
 
 unsafe fn align_to_pointer<T>(ptr: *T) -> *T {
     let align = sys::min_align_of::<*T>();
-    let ptr: uint = cast::transmute(ptr);
+    let ptr = ptr as uint;
     let ptr = (ptr + (align - 1)) & -align;
-    return cast::transmute(ptr);
+    return ptr as *T;
 }
 
 unsafe fn get_safe_point_count() -> uint {
@@ -126,8 +126,8 @@ type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc) -> bool;
 // Walks the list of roots for the given safe point, and calls visitor
 // on each root.
 unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
-    let fp_bytes: *u8 = cast::transmute(fp);
-    let sp_meta: *u32 = cast::transmute(sp.sp_meta);
+    let fp_bytes = fp as *u8;
+    let sp_meta = sp.sp_meta as *u32;
 
     let num_stack_roots = *sp_meta as uint;
     let num_reg_roots = *ptr::offset(sp_meta, 1) as uint;
@@ -173,9 +173,9 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
 
 // Is fp contained in segment?
 unsafe fn is_frame_in_segment(fp: *Word, segment: *StackSegment) -> bool {
-    let begin: Word = cast::transmute(segment);
-    let end: Word = cast::transmute((*segment).end);
-    let frame: Word = cast::transmute(fp);
+    let begin = segment as Word;
+    let end = (*segment).end as Word;
+    let frame = fp as Word;
 
     return begin <= frame && frame <= end;
 }
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index 0c2a7bb7b40..36645a555bb 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -17,8 +17,6 @@ implementing the `Iterator` trait.
 
 */
 
-#[allow(default_methods)]; // still off by default in stage0
-
 use cmp;
 use iter::Times;
 use num::{Zero, One};
@@ -96,7 +94,7 @@ impl<A, T: DoubleEndedIterator<A>> Iterator<A> for InvertIterator<A, T> {
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-impl<A, T: Iterator<A>> DoubleEndedIterator<A> for InvertIterator<A, T> {
+impl<A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for InvertIterator<A, T> {
     #[inline]
     fn next_back(&mut self) -> Option<A> { self.iter.next() }
 }
@@ -343,6 +341,18 @@ pub trait IteratorUtil<A> {
     /// ~~~
     fn collect<B: FromIterator<A, Self>>(&mut self) -> B;
 
+    /// Loops through the entire iterator, collecting all of the elements into
+    /// a unique vector. This is simply collect() specialized for vectors.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = [1, 2, 3, 4, 5];
+    /// let b: ~[int] = a.iter().transform(|&x| x).to_owned_vec();
+    /// assert!(a == b);
+    /// ~~~
+    fn to_owned_vec(&mut self) -> ~[A];
+
     /// Loops through `n` iterations, returning the `n`th element of the
     /// iterator.
     ///
@@ -539,6 +549,11 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
         FromIterator::from_iterator(self)
     }
 
+    #[inline]
+    fn to_owned_vec(&mut self) -> ~[A] {
+        self.collect()
+    }
+
     /// Return the `n`th item yielded by an iterator.
     #[inline]
     fn nth(&mut self, mut n: uint) -> Option<A> {
diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs
index 2c9fcb2999f..bd4dc69537c 100644
--- a/src/libstd/managed.rs
+++ b/src/libstd/managed.rs
@@ -14,27 +14,8 @@ use ptr::to_unsafe_ptr;
 
 #[cfg(not(test))] use cmp::{Eq, Ord};
 
-pub mod raw {
-    use std::unstable::intrinsics::TyDesc;
-
-    pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
-    pub static RC_IMMORTAL : uint = 0x77777777;
-
-    #[allow(missing_doc)]
-    pub struct BoxHeaderRepr {
-        ref_count: uint,
-        type_desc: *TyDesc,
-        prev: *BoxRepr,
-        next: *BoxRepr,
-    }
-
-    #[allow(missing_doc)]
-    pub struct BoxRepr {
-        header: BoxHeaderRepr,
-        data: u8
-    }
-
-}
+pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
+pub static RC_IMMORTAL : uint = 0x77777777;
 
 /// Determine if two shared boxes point to the same object
 #[inline]
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index c4fee908266..eb3f227562a 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -118,13 +118,13 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns true if the option equals `none`
+    /// Returns true if the option equals `None`
     #[inline]
     pub fn is_none(&self) -> bool {
         match *self { None => true, Some(_) => false }
     }
 
-    /// Returns true if the option contains some value
+    /// Returns true if the option contains a `Some` value
     #[inline]
     pub fn is_some(&self) -> bool { !self.is_none() }
 
@@ -158,6 +158,17 @@ impl<T> Option<T> {
         }
     }
 
+    /// Update an optional value by optionally running its content by mut reference
+    /// through a function that returns an option.
+    #[inline]
+    pub fn chain_mut_ref<'a, U>(&'a mut self, f: &fn(x: &'a mut T) -> Option<U>)
+                                -> Option<U> {
+        match *self {
+            Some(ref mut x) => f(x),
+            None => None
+        }
+    }
+
     /// Filters an optional value using given function.
     #[inline(always)]
     pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option<T> {
@@ -167,19 +178,19 @@ impl<T> Option<T> {
         }
     }
 
-    /// Maps a `some` value from one type to another by reference
+    /// Maps a `Some` value from one type to another by reference
     #[inline]
     pub fn map<'a, U>(&'a self, f: &fn(&'a T) -> U) -> Option<U> {
         match *self { Some(ref x) => Some(f(x)), None => None }
     }
 
-    /// Maps a `some` value from one type to another by a mutable reference
+    /// Maps a `Some` value from one type to another by a mutable reference
     #[inline]
     pub fn map_mut<'a, U>(&'a mut self, f: &fn(&'a mut T) -> U) -> Option<U> {
         match *self { Some(ref mut x) => Some(f(x)), None => None }
     }
 
-    /// Maps a `some` value from one type to another by a mutable reference,
+    /// Maps a `Some` value from one type to another by a mutable reference,
     /// or returns a default value.
     #[inline]
     pub fn map_mut_default<'a, U>(&'a mut self, def: U, f: &fn(&'a mut T) -> U) -> U {
@@ -260,7 +271,7 @@ impl<T> Option<T> {
     pub fn get_ref<'a>(&'a self) -> &'a T {
         match *self {
           Some(ref x) => x,
-          None => fail!("option::get_ref none")
+          None => fail!("option::get_ref None")
         }
     }
 
@@ -282,7 +293,7 @@ impl<T> Option<T> {
     pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
         match *self {
           Some(ref mut x) => x,
-          None => fail!("option::get_mut_ref none")
+          None => fail!("option::get_mut_ref None")
         }
     }
 
@@ -306,7 +317,7 @@ impl<T> Option<T> {
          */
         match self {
           Some(x) => x,
-          None => fail!("option::unwrap none")
+          None => fail!("option::unwrap None")
         }
     }
 
@@ -320,7 +331,7 @@ impl<T> Option<T> {
      */
     #[inline]
     pub fn take_unwrap(&mut self) -> T {
-        if self.is_none() { fail!("option::take_unwrap none") }
+        if self.is_none() { fail!("option::take_unwrap None") }
         self.take().unwrap()
     }
 
@@ -330,7 +341,7 @@ impl<T> Option<T> {
      *
      * # Failure
      *
-     * Fails if the value equals `none`
+     * Fails if the value equals `None`
      */
     #[inline]
     pub fn expect(self, reason: &str) -> T {
@@ -358,7 +369,7 @@ impl<T> Option<T> {
     pub fn get(self) -> T {
         match self {
           Some(x) => return x,
-          None => fail!("option::get none")
+          None => fail!("option::get None")
         }
     }
 
@@ -368,7 +379,7 @@ impl<T> Option<T> {
         match self { Some(x) => x, None => def }
     }
 
-    /// Applies a function zero or more times until the result is none.
+    /// Applies a function zero or more times until the result is None.
     #[inline]
     pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
         let mut opt = self;
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index d49d54ae68f..1d093c4c14b 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -19,7 +19,7 @@ Runtime type reflection
 use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
 use libc::c_void;
 use sys;
-use vec;
+use unstable::raw;
 
 /**
  * Trait for visitor that wishes to reflect on data. To use this, create a
@@ -260,7 +260,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
     }
 
     fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
-        self.align_to::<vec::UnboxedVecRepr>();
+        self.align_to::<raw::Vec<()>>();
         if ! self.inner.visit_vec(mtbl, inner) { return false; }
         true
     }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index 07fd82e1616..eb4e1918add 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -22,21 +22,17 @@ use container::Container;
 use io::{Writer, WriterUtil};
 use iterator::IteratorUtil;
 use libc::c_void;
-use managed;
 use ptr;
 use reflect;
 use reflect::{MovePtr, align};
 use str::StrSlice;
 use to_str::ToStr;
-use vec::raw::{VecRepr, SliceRepr};
-use vec;
-use vec::{OwnedVector, UnboxedVecRepr};
+use vec::OwnedVector;
 use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
+use unstable::raw;
 
 #[cfg(test)] use io;
 
-pub use managed::raw::BoxRepr;
-
 /// Helpers
 
 trait EscapedCharWriter {
@@ -198,11 +194,11 @@ impl ReprVisitor {
 
     pub fn write_vec_range(&self,
                            _mtbl: uint,
-                           ptr: *u8,
+                           ptr: *(),
                            len: uint,
                            inner: *TyDesc)
                            -> bool {
-        let mut p = ptr;
+        let mut p = ptr as *u8;
         let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
         self.writer.write_char('[');
         let mut first = true;
@@ -225,7 +221,7 @@ impl ReprVisitor {
 
     pub fn write_unboxed_vec_repr(&self,
                                   mtbl: uint,
-                                  v: &UnboxedVecRepr,
+                                  v: &raw::Vec<()>,
                                   inner: *TyDesc)
                                   -> bool {
         self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data),
@@ -289,7 +285,7 @@ impl TyVisitor for ReprVisitor {
     fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool {
         self.writer.write_char('@');
         self.write_mut_qualifier(mtbl);
-        do self.get::<&managed::raw::BoxRepr> |b| {
+        do self.get::<&raw::Box<()>> |b| {
             let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
             self.visit_ptr_inner(p, inner);
         }
@@ -304,7 +300,7 @@ impl TyVisitor for ReprVisitor {
 
     fn visit_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
         self.writer.write_char('~');
-        do self.get::<&managed::raw::BoxRepr> |b| {
+        do self.get::<&raw::Box<()>> |b| {
             let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
             self.visit_ptr_inner(p, inner);
         }
@@ -330,35 +326,35 @@ impl TyVisitor for ReprVisitor {
 
 
     fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
-        do self.get::<vec::UnboxedVecRepr> |b| {
+        do self.get::<raw::Vec<()>> |b| {
             self.write_unboxed_vec_repr(mtbl, b, inner);
         }
     }
 
     fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool {
-        do self.get::<&VecRepr> |b| {
+        do self.get::<&raw::Box<raw::Vec<()>>> |b| {
             self.writer.write_char('@');
             self.write_mut_qualifier(mtbl);
-            self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
+            self.write_unboxed_vec_repr(mtbl, &b.data, inner);
         }
     }
 
     fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
-        do self.get::<&UnboxedVecRepr> |b| {
+        do self.get::<&raw::Vec<()>> |b| {
             self.writer.write_char('~');
             self.write_unboxed_vec_repr(mtbl, *b, inner);
         }
     }
 
     fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
-        do self.get::<&VecRepr> |b| {
+        do self.get::<&raw::Box<raw::Vec<()>>> |b| {
             self.writer.write_char('~');
-            self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
+            self.write_unboxed_vec_repr(mtbl, &b.data, inner);
         }
     }
 
     fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool {
-        do self.get::<SliceRepr> |s| {
+        do self.get::<raw::Slice<()>> |s| {
             self.writer.write_char('&');
             self.write_vec_range(mtbl, s.data, s.len, inner);
         }
@@ -366,7 +362,7 @@ impl TyVisitor for ReprVisitor {
 
     fn visit_evec_fixed(&self, _n: uint, sz: uint, _align: uint,
                         mtbl: uint, inner: *TyDesc) -> bool {
-        do self.get::<u8> |b| {
+        do self.get::<()> |b| {
             self.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), sz, inner);
         }
     }
@@ -547,9 +543,9 @@ impl TyVisitor for ReprVisitor {
 
     fn visit_opaque_box(&self) -> bool {
         self.writer.write_char('@');
-        do self.get::<&managed::raw::BoxRepr> |b| {
+        do self.get::<&raw::Box<()>> |b| {
             let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
-            self.visit_ptr_inner(p, b.header.type_desc);
+            self.visit_ptr_inner(p, b.type_desc);
         }
     }
 
diff --git a/src/libstd/rt/borrowck.rs b/src/libstd/rt/borrowck.rs
index 1a468fcf215..2d489e4dbc3 100644
--- a/src/libstd/rt/borrowck.rs
+++ b/src/libstd/rt/borrowck.rs
@@ -12,12 +12,12 @@ use cast::transmute;
 use libc::{c_char, c_void, size_t, STDERR_FILENO};
 use io;
 use io::{Writer, WriterUtil};
-use managed::raw::BoxRepr;
 use option::{Option, None, Some};
 use uint;
 use str;
 use str::{OwnedStr, StrSlice};
 use sys;
+use unstable::raw;
 use vec::ImmutableVector;
 
 #[allow(non_camel_case_types)]
@@ -29,7 +29,7 @@ static ALL_BITS: uint = FROZEN_BIT | MUT_BIT;
 
 #[deriving(Eq)]
 struct BorrowRecord {
-    box: *mut BoxRepr,
+    box: *mut raw::Box<()>,
     file: *c_char,
     line: size_t
 }
@@ -70,7 +70,7 @@ pub unsafe fn clear_task_borrow_list() {
     let _ = try_take_task_borrow_list();
 }
 
-unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
+unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
     debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
 
     match try_take_task_borrow_list() {
@@ -172,8 +172,8 @@ impl DebugPrints for io::fd_t {
 
 #[inline]
 pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
-    let a: *mut BoxRepr = transmute(a);
-    let old_ref_count = (*a).header.ref_count;
+    let a = a as *mut raw::Box<()>;
+    let old_ref_count = (*a).ref_count;
     let new_ref_count = old_ref_count | FROZEN_BIT;
 
     debug_borrow("borrow_as_imm:", a, old_ref_count, new_ref_count, file, line);
@@ -182,15 +182,15 @@ pub unsafe fn borrow_as_imm(a: *u8, file: *c_char, line: size_t) -> uint {
         fail_borrowed(a, file, line);
     }
 
-    (*a).header.ref_count = new_ref_count;
+    (*a).ref_count = new_ref_count;
 
     old_ref_count
 }
 
 #[inline]
 pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
-    let a: *mut BoxRepr = transmute(a);
-    let old_ref_count = (*a).header.ref_count;
+    let a = a as *mut raw::Box<()>;
+    let old_ref_count = (*a).ref_count;
     let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT;
 
     debug_borrow("borrow_as_mut:", a, old_ref_count, new_ref_count, file, line);
@@ -199,7 +199,7 @@ pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
         fail_borrowed(a, file, line);
     }
 
-    (*a).header.ref_count = new_ref_count;
+    (*a).ref_count = new_ref_count;
 
     old_ref_count
 }
@@ -208,7 +208,7 @@ pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
                             file: *c_char, line: size_t) {
     if (old_ref_count & ALL_BITS) == 0 {
         // was not borrowed before
-        let a: *mut BoxRepr = transmute(a);
+        let a = a as *mut raw::Box<()>;
         debug_borrow("record_borrow:", a, old_ref_count, 0, file, line);
         do swap_task_borrow_list |borrow_list| {
             let mut borrow_list = borrow_list;
@@ -223,7 +223,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
     if (old_ref_count & ALL_BITS) == 0 {
         // was not borrowed before, so we should find the record at
         // the end of the list
-        let a: *mut BoxRepr = transmute(a);
+        let a = a as *mut raw::Box<()>;
         debug_borrow("unrecord_borrow:", a, old_ref_count, 0, file, line);
         do swap_task_borrow_list |borrow_list| {
             let mut borrow_list = borrow_list;
@@ -246,15 +246,15 @@ pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
     // Sometimes the box is null, if it is conditionally frozen.
     // See e.g. #4904.
     if !a.is_null() {
-        let a: *mut BoxRepr = transmute(a);
-        let old_ref_count = (*a).header.ref_count;
+        let a = a as *mut raw::Box<()>;
+        let old_ref_count = (*a).ref_count;
         let new_ref_count =
             (old_ref_count & !ALL_BITS) | (orig_ref_count & ALL_BITS);
 
         debug_borrow("return_to_mut:",
                      a, old_ref_count, new_ref_count, file, line);
 
-        (*a).header.ref_count = new_ref_count;
+        (*a).ref_count = new_ref_count;
     }
 }
 
@@ -262,8 +262,8 @@ pub unsafe fn return_to_mut(a: *u8, orig_ref_count: uint,
 pub unsafe fn check_not_borrowed(a: *u8,
                                  file: *c_char,
                                  line: size_t) {
-    let a: *mut BoxRepr = transmute(a);
-    let ref_count = (*a).header.ref_count;
+    let a = a as *mut raw::Box<()>;
+    let ref_count = (*a).ref_count;
     debug_borrow("check_not_borrowed:", a, ref_count, 0, file, line);
     if (ref_count & FROZEN_BIT) != 0 {
         fail_borrowed(a, file, line);
diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs
index 54e9cb263db..7488b08da42 100644
--- a/src/libstd/rt/global_heap.rs
+++ b/src/libstd/rt/global_heap.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use libc::{c_void, c_char, size_t, uintptr_t, free, malloc, realloc};
-use managed::raw::{BoxHeaderRepr, BoxRepr};
 use unstable::intrinsics::TyDesc;
+use unstable::raw;
 use sys::size_of;
 
 extern {
@@ -20,7 +20,7 @@ extern {
 
 #[inline]
 fn get_box_size(body_size: uint, body_align: uint) -> uint {
-    let header_size = size_of::<BoxHeaderRepr>();
+    let header_size = size_of::<raw::Box<()>>();
     // FIXME (#2699): This alignment calculation is suspicious. Is it right?
     let total_size = align_to(header_size, body_align) + body_size;
     total_size
@@ -82,8 +82,8 @@ pub unsafe fn closure_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
     let total_size = get_box_size(size, (*td).align);
     let p = malloc_raw(total_size as uint);
 
-    let box: *mut BoxRepr = p as *mut BoxRepr;
-    (*box).header.type_desc = td;
+    let box = p as *mut raw::Box<()>;
+    (*box).type_desc = td;
 
     box as *c_char
 }
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index 85917ae3edf..cd8e8549211 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -13,11 +13,11 @@
 use libc;
 use libc::{c_void, uintptr_t, size_t};
 use ops::Drop;
-use repr::BoxRepr;
 use rt;
 use rt::OldTaskContext;
 use rt::local::Local;
 use rt::task::Task;
+use unstable::raw;
 
 type MemoryRegion = c_void;
 
@@ -26,7 +26,7 @@ struct Env { priv opaque: () }
 struct BoxedRegion {
     env: *Env,
     backing_region: *MemoryRegion,
-    live_allocs: *BoxRepr
+    live_allocs: *raw::Box<()>,
 }
 
 pub type OpaqueBox = c_void;
@@ -103,7 +103,7 @@ pub unsafe fn local_free(ptr: *libc::c_char) {
     }
 }
 
-pub fn live_allocs() -> *BoxRepr {
+pub fn live_allocs() -> *raw::Box<()> {
     let region = match rt::context() {
         OldTaskContext => {
             unsafe { rust_current_boxed_region() }
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index d8d61806a5b..33cfd69fcd2 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -10,9 +10,9 @@
 
 use either::{Left, Right};
 use option::{Option, Some, None};
-use sys;
 use cast::transmute;
 use clone::Clone;
+use unstable::raw;
 
 use super::sleeper_list::SleeperList;
 use super::work_queue::WorkQueue;
@@ -698,7 +698,7 @@ impl SchedHandle {
 
 // XXX: Some hacks to put a &fn in Scheduler without borrowck
 // complaining
-type UnsafeTaskReceiver = sys::Closure;
+type UnsafeTaskReceiver = raw::Closure;
 trait ClosureConverter {
     fn from_fn(&fn(&mut Scheduler, BlockedTask)) -> Self;
     fn to_fn(self) -> &fn(&mut Scheduler, BlockedTask);
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index d2975148350..8cf864b9222 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -281,7 +281,7 @@ static UNWIND_TOKEN: uintptr_t = 839147;
 
 impl Unwinder {
     pub fn try(&mut self, f: &fn()) {
-        use sys::Closure;
+        use unstable::raw::Closure;
 
         unsafe {
             let closure: Closure = transmute(f);
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 636bbc48f8e..c600e7f6c09 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -31,6 +31,7 @@ use ptr;
 use ptr::RawPtr;
 use to_str::ToStr;
 use uint;
+use unstable::raw::Repr;
 use vec;
 use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector, MutableVector};
 
@@ -114,9 +115,9 @@ pub fn from_bytes_with_null<'a>(vv: &'a [u8]) -> &'a str {
 pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str {
     unsafe {
         assert!(is_utf8(vector));
-        let (ptr, len): (*u8, uint) = ::cast::transmute(vector);
-        let string: &'a str = ::cast::transmute((ptr, len + 1));
-        string
+        let mut s = vector.repr();
+        s.len += 1;
+        cast::transmute(s)
     }
 }
 
@@ -142,7 +143,7 @@ impl ToStr for @str {
  */
 pub fn from_byte(b: u8) -> ~str {
     assert!(b < 128u8);
-    unsafe { ::cast::transmute(~[b, 0u8]) }
+    unsafe { cast::transmute(~[b, 0u8]) }
 }
 
 /// Convert a char to a string
@@ -217,7 +218,7 @@ impl<'self, S: Str> StrVector for &'self [S] {
             do s.as_mut_buf |buf, _| {
                 do sep.as_imm_buf |sepbuf, seplen| {
                     let seplen = seplen - 1;
-                    let mut buf = ::cast::transmute_mut_unsafe(buf);
+                    let mut buf = cast::transmute_mut_unsafe(buf);
                     for self.iter().advance |ss| {
                         do ss.as_slice().as_imm_buf |ssbuf, sslen| {
                             let sslen = sslen - 1;
@@ -771,10 +772,10 @@ pub mod raw {
     use cast;
     use libc;
     use ptr;
-    use str::raw;
-    use str::{is_utf8};
+    use str::is_utf8;
     use vec;
     use vec::MutableVector;
+    use unstable::raw::{Slice, String};
 
     /// Create a Rust string from a null-terminated *u8 buffer
     pub unsafe fn from_buf(buf: *u8) -> ~str {
@@ -797,17 +798,17 @@ pub mod raw {
         v.push(0u8);
 
         assert!(is_utf8(v));
-        return ::cast::transmute(v);
+        return cast::transmute(v);
     }
 
     /// Create a Rust string from a null-terminated C string
     pub unsafe fn from_c_str(c_str: *libc::c_char) -> ~str {
-        from_buf(::cast::transmute(c_str))
+        from_buf(c_str as *u8)
     }
 
     /// Create a Rust string from a `*c_char` buffer of the given length
     pub unsafe fn from_c_str_len(c_str: *libc::c_char, len: uint) -> ~str {
-        from_buf_len(::cast::transmute(c_str), len)
+        from_buf_len(c_str as *u8, len)
     }
 
     /// Converts a vector of bytes to a new owned string.
@@ -832,7 +833,7 @@ pub mod raw {
     }
 
     /// Converts a byte to a string.
-    pub unsafe fn from_byte(u: u8) -> ~str { raw::from_bytes([u]) }
+    pub unsafe fn from_byte(u: u8) -> ~str { from_bytes([u]) }
 
     /// Form a slice from a C string. Unsafe because the caller must ensure the
     /// C string has the static lifetime, or else the return value may be
@@ -845,9 +846,9 @@ pub mod raw {
             len += 1u;
             curr = ptr::offset(s, len);
         }
-        let v = (s, len + 1);
-        assert!(is_utf8(::cast::transmute(v)));
-        ::cast::transmute(v)
+        let v = Slice { data: s, len: len + 1 };
+        assert!(is_utf8(cast::transmute(v)));
+        cast::transmute(v)
     }
 
     /**
@@ -866,8 +867,10 @@ pub mod raw {
              assert!((begin <= end));
              assert!((end <= n));
 
-             let tuple = (ptr::offset(sbuf, begin), end - begin + 1);
-             ::cast::transmute(tuple)
+             cast::transmute(Slice {
+                 data: ptr::offset(sbuf, begin),
+                 len: end - begin + 1,
+             })
         }
     }
 
@@ -909,11 +912,10 @@ pub mod raw {
     /// Sets the length of the string and adds the null terminator
     #[inline]
     pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
-        let v: **mut vec::UnboxedVecRepr = cast::transmute(v);
-        let repr: *mut vec::UnboxedVecRepr = *v;
+        let v: **mut String = cast::transmute(v);
+        let repr = *v;
         (*repr).fill = new_len + 1u;
-        let null = ptr::mut_offset(cast::transmute(&((*repr).data)),
-                                   new_len);
+        let null = ptr::mut_offset(&mut ((*repr).data), new_len);
         *null = 0u8;
     }
 
@@ -1595,7 +1597,7 @@ impl<'self> StrSlice<'self> for &'self str {
         let v = at_vec::from_fn(self.len() + 1, |i| {
             if i == self.len() { 0 } else { self[i] }
         });
-        unsafe { ::cast::transmute(v) }
+        unsafe { cast::transmute(v) }
     }
 
     /// Converts to a vector of `u16` encoded as UTF-16.
@@ -1750,9 +1752,9 @@ impl<'self> StrSlice<'self> for &'self str {
      */
     fn as_bytes(&self) -> &'self [u8] {
         unsafe {
-            let (ptr, len): (*u8, uint) = ::cast::transmute(*self);
-            let outgoing_tuple: (*u8, uint) = (ptr, len - 1);
-            ::cast::transmute(outgoing_tuple)
+            let mut slice = self.repr();
+            slice.len -= 1;
+            cast::transmute(slice)
         }
     }
 
@@ -2001,7 +2003,7 @@ impl NullTerminatedStr for ~str {
      */
     #[inline]
     fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] {
-        let ptr: &'a ~[u8] = unsafe { ::cast::transmute(self) };
+        let ptr: &'a ~[u8] = unsafe { cast::transmute(self) };
         let slice: &'a [u8] = *ptr;
         slice
     }
@@ -2014,7 +2016,7 @@ impl NullTerminatedStr for @str {
      */
     #[inline]
     fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] {
-        let ptr: &'a @[u8] = unsafe { ::cast::transmute(self) };
+        let ptr: &'a @[u8] = unsafe { cast::transmute(self) };
         let slice: &'a [u8] = *ptr;
         slice
     }
@@ -2058,7 +2060,7 @@ impl OwnedStr for ~str {
             do self.as_imm_buf |lbuf, _llen| {
                 do rhs.as_imm_buf |rbuf, _rlen| {
                     let dst = ptr::offset(lbuf, llen);
-                    let dst = ::cast::transmute_mut_unsafe(dst);
+                    let dst = cast::transmute_mut_unsafe(dst);
                     ptr::copy_memory(dst, rbuf, rlen);
                 }
             }
@@ -2076,7 +2078,7 @@ impl OwnedStr for ~str {
             do self.as_imm_buf |lbuf, _llen| {
                 do rhs.as_imm_buf |rbuf, _rlen| {
                     let dst = ptr::offset(lbuf, llen);
-                    let dst = ::cast::transmute_mut_unsafe(dst);
+                    let dst = cast::transmute_mut_unsafe(dst);
                     ptr::copy_memory(dst, rbuf, rlen);
                 }
             }
@@ -2232,7 +2234,7 @@ impl OwnedStr for ~str {
     /// string, and includes the null terminator.
     #[inline]
     fn to_bytes_with_null(self) -> ~[u8] {
-        unsafe { ::cast::transmute(self) }
+        unsafe { cast::transmute(self) }
     }
 
     #[inline]
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs
index 28cd2345aab..5cf77d901db 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -22,12 +22,6 @@ use str::StrSlice;
 use str;
 use unstable::intrinsics;
 
-/// The representation of a Rust closure
-pub struct Closure {
-    code: *(),
-    env: *(),
-}
-
 pub mod rustrt {
     use libc::{c_char, size_t};
 
@@ -278,6 +272,7 @@ mod tests {
 
     #[test]
     fn synthesize_closure() {
+        use unstable::raw::Closure;
         unsafe {
             let x = 10;
             let f: &fn(int) -> int = |y| x + y;
diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs
index d5f4973e8c7..477981c65e5 100644
--- a/src/libstd/task/local_data_priv.rs
+++ b/src/libstd/task/local_data_priv.rs
@@ -15,8 +15,8 @@ use libc;
 use local_data;
 use prelude::*;
 use ptr;
-use sys;
 use task::rt;
+use unstable::raw;
 use util;
 
 use super::rt::rust_task;
@@ -158,7 +158,7 @@ unsafe fn get_local_map(handle: Handle) -> &mut TaskLocalMap {
 }
 
 unsafe fn key_to_key_value<T: 'static>(key: local_data::Key<T>) -> *libc::c_void {
-    let pair: sys::Closure = cast::transmute_copy(&key);
+    let pair: raw::Closure = cast::transmute_copy(&key);
     return pair.code as *libc::c_void;
 }
 
diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs
index b595d3e1a80..712c32d2436 100644
--- a/src/libstd/unstable/atomics.rs
+++ b/src/libstd/unstable/atomics.rs
@@ -96,7 +96,7 @@ impl AtomicFlag {
      */
     #[inline]
     pub fn test_and_set(&mut self, order: Ordering) -> bool {
-        unsafe {atomic_compare_and_swap(&mut self.v, 0, 1, order) > 0}
+        unsafe { atomic_compare_and_swap(&mut self.v, 0, 1, order) > 0 }
     }
 }
 
@@ -121,7 +121,7 @@ impl AtomicBool {
     pub fn swap(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { 1 } else { 0 };
 
-        unsafe { atomic_swap(&mut self.v, val, order) > 0}
+        unsafe { atomic_swap(&mut self.v, val, order) > 0 }
     }
 
     #[inline]
@@ -131,6 +131,38 @@ impl AtomicBool {
 
         unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) > 0 }
     }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_and(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_and(&mut self.v, val, order) > 0 }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_nand(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_nand(&mut self.v, val, order) > 0 }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_or(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_or(&mut self.v, val, order) > 0 }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_xor(&mut self, val: bool, order: Ordering) -> bool {
+        let val = if val { 1 } else { 0 };
+
+        unsafe { atomic_xor(&mut self.v, val, order) > 0 }
+    }
 }
 
 impl AtomicInt {
@@ -169,6 +201,18 @@ impl AtomicInt {
     pub fn fetch_sub(&mut self, val: int, order: Ordering) -> int {
         unsafe { atomic_sub(&mut self.v, val, order) }
     }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_min(&mut self, val: int, order: Ordering) -> int {
+        unsafe { atomic_min(&mut self.v, val, order) }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_max(&mut self, val: int, order: Ordering) -> int {
+        unsafe { atomic_max(&mut self.v, val, order) }
+    }
 }
 
 impl AtomicUint {
@@ -207,6 +251,18 @@ impl AtomicUint {
     pub fn fetch_sub(&mut self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_sub(&mut self.v, val, order) }
     }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_min(&mut self, val: uint, order: Ordering) -> uint {
+        unsafe { atomic_umin(&mut self.v, val, order) }
+    }
+
+    /// Returns the old value
+    #[inline]
+    pub fn fetch_max(&mut self, val: uint, order: Ordering) -> uint {
+        unsafe { atomic_umax(&mut self.v, val, order) }
+    }
 }
 
 impl<T> AtomicPtr<T> {
@@ -395,6 +451,125 @@ pub unsafe fn atomic_compare_and_swap<T>(dst:&mut T, old:T, new:T, order: Orderi
     })
 }
 
+#[inline]
+pub unsafe fn atomic_and<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_and_acq(dst, val),
+        Release => intrinsics::atomic_and_rel(dst, val),
+        AcqRel  => intrinsics::atomic_and_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_and_relaxed(dst, val),
+        _       => intrinsics::atomic_and(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_nand<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_nand_acq(dst, val),
+        Release => intrinsics::atomic_nand_rel(dst, val),
+        AcqRel  => intrinsics::atomic_nand_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
+        _       => intrinsics::atomic_nand(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_or<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_or_acq(dst, val),
+        Release => intrinsics::atomic_or_rel(dst, val),
+        AcqRel  => intrinsics::atomic_or_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_or_relaxed(dst, val),
+        _       => intrinsics::atomic_or(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_xor<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_xor_acq(dst, val),
+        Release => intrinsics::atomic_xor_rel(dst, val),
+        AcqRel  => intrinsics::atomic_xor_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
+        _       => intrinsics::atomic_xor(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_max<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_max_acq(dst, val),
+        Release => intrinsics::atomic_max_rel(dst, val),
+        AcqRel  => intrinsics::atomic_max_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_max_relaxed(dst, val),
+        _       => intrinsics::atomic_max(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_min<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_min_acq(dst, val),
+        Release => intrinsics::atomic_min_rel(dst, val),
+        AcqRel  => intrinsics::atomic_min_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_min_relaxed(dst, val),
+        _       => intrinsics::atomic_min(dst, val)
+    })
+}
+
+#[inline]
+pub unsafe fn atomic_umax<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_umax_acq(dst, val),
+        Release => intrinsics::atomic_umax_rel(dst, val),
+        AcqRel  => intrinsics::atomic_umax_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
+        _       => intrinsics::atomic_umax(dst, val)
+    })
+}
+
+
+#[inline]
+pub unsafe fn atomic_umin<T>(dst: &mut T, val: T, order: Ordering) -> T {
+    let dst = cast::transmute(dst);
+    let val = cast::transmute(val);
+
+    cast::transmute(match order {
+        Acquire => intrinsics::atomic_umin_acq(dst, val),
+        Release => intrinsics::atomic_umin_rel(dst, val),
+        AcqRel  => intrinsics::atomic_umin_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
+        _       => intrinsics::atomic_umin(dst, val)
+    })
+}
+
+
 #[cfg(test)]
 mod test {
     use option::*;
@@ -448,4 +623,11 @@ mod test {
         assert!(p.fill(~2, SeqCst).is_none()); // shouldn't fail
         assert_eq!(p.take(SeqCst), Some(~2));
     }
+
+    #[test]
+    fn bool_and() {
+        let mut a = AtomicBool::new(true);
+        assert_eq!(a.fetch_and(false, SeqCst),true);
+        assert_eq!(a.load(SeqCst),false);
+    }
 }
diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs
index d6fd2cbcd1e..0d8cb1e8f74 100644
--- a/src/libstd/unstable/mod.rs
+++ b/src/libstd/unstable/mod.rs
@@ -26,6 +26,7 @@ pub mod extfmt;
 pub mod lang;
 pub mod sync;
 pub mod atomics;
+pub mod raw;
 
 /**
 
diff --git a/src/libstd/unstable/raw.rs b/src/libstd/unstable/raw.rs
new file mode 100644
index 00000000000..0e074b53d6b
--- /dev/null
+++ b/src/libstd/unstable/raw.rs
@@ -0,0 +1,61 @@
+// 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.
+
+use cast;
+use unstable::intrinsics::TyDesc;
+
+/// The representation of a Rust managed box
+pub struct Box<T> {
+    ref_count: uint,
+    type_desc: *TyDesc,
+    prev: *Box<T>,
+    next: *Box<T>,
+    data: T
+}
+
+/// The representation of a Rust vector
+pub struct Vec<T> {
+    fill: uint,
+    alloc: uint,
+    data: T
+}
+
+/// The representation of a Rust string
+pub type String = Vec<u8>;
+
+/// The representation of a Rust slice
+pub struct Slice<T> {
+    data: *T,
+    len: uint
+}
+
+/// The representation of a Rust closure
+pub struct Closure {
+    code: *(),
+    env: *(),
+}
+
+/// This trait is meant to map equivalences between raw structs and their
+/// corresponding rust values.
+pub trait Repr<T> {
+    /// This function "unwraps" a rust value (without consuming it) into its raw
+    /// struct representation. This can be used to read/write different values
+    /// for the struct. This is a safe method because by default it does not
+    /// give write-access to the struct returned.
+    fn repr(&self) -> T { unsafe { cast::transmute_copy(self) } }
+}
+
+impl<'self, T> Repr<Slice<T>> for &'self [T] {}
+impl<'self> Repr<Slice<u8>> for &'self str {}
+impl<T> Repr<*Box<T>> for @T {}
+impl<T> Repr<*Box<Vec<T>>> for @[T] {}
+
+// sure would be nice to have this
+// impl<T> Repr<*Vec<T>> for ~[T] {}
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 5f8a2796248..87ac4037e8e 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -12,7 +12,6 @@
 
 #[warn(non_camel_case_types)];
 
-use cast::transmute;
 use cast;
 use clone::Clone;
 use container::{Container, Mutable};
@@ -32,6 +31,7 @@ use sys::size_of;
 use uint;
 use unstable::intrinsics;
 use unstable::intrinsics::{get_tydesc, contains_managed};
+use unstable::raw::{Box, Repr, Slice, Vec};
 use vec;
 use util;
 
@@ -96,7 +96,7 @@ pub fn with_capacity<T>(capacity: uint) -> ~[T] {
             vec
         } else {
             let alloc = capacity * sys::nonzero_size_of::<T>();
-            let ptr = malloc_raw(alloc + sys::size_of::<UnboxedVecRepr>()) as *mut UnboxedVecRepr;
+            let ptr = malloc_raw(alloc + sys::size_of::<Vec<()>>()) as *mut Vec<()>;
             (*ptr).alloc = alloc;
             (*ptr).fill = 0;
             cast::transmute(ptr)
@@ -736,8 +736,10 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
         assert!(end <= self.len());
         do self.as_imm_buf |p, _len| {
             unsafe {
-                transmute((ptr::offset(p, start),
-                           (end - start) * sys::nonzero_size_of::<T>()))
+                cast::transmute(Slice {
+                    data: ptr::offset(p, start),
+                    len: (end - start) * sys::nonzero_size_of::<T>(),
+                })
             }
         }
     }
@@ -767,8 +769,8 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
         unsafe {
             let p = vec::raw::to_ptr(self);
             VecIterator{ptr: p,
-                        end: cast::transmute(p as uint + self.len() *
-                                             sys::nonzero_size_of::<T>()),
+                        end: (p as uint + self.len() *
+                              sys::nonzero_size_of::<T>()) as *T,
                         lifetime: cast::transmute(p)}
         }
     }
@@ -947,8 +949,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     /// bounds checking.
     #[inline]
     unsafe fn unsafe_ref(&self, index: uint) -> *T {
-        let (ptr, _): (*T, uint) = transmute(*self);
-        ptr.offset(index)
+        self.repr().data.offset(index)
     }
 
     /**
@@ -1002,11 +1003,8 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
         // into `s` and pass them to `f()`, but in fact they are potentially
         // pointing at *mutable memory*.  Use `as_mut_buf` instead!
 
-        unsafe {
-            let v : *(*T,uint) = transmute(self);
-            let (buf,len) = *v;
-            f(buf, len / sys::nonzero_size_of::<T>())
-        }
+        let s = self.repr();
+        f(s.data, s.len / sys::nonzero_size_of::<T>())
     }
 }
 
@@ -1158,17 +1156,17 @@ impl<T> OwnedVector<T> for ~[T] {
             unsafe {
                 let td = get_tydesc::<T>();
                 if contains_managed::<T>() {
-                    let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
+                    let ptr: *mut *mut Box<Vec<()>> = cast::transmute(self);
                     ::at_vec::raw::reserve_raw(td, ptr, n);
                 } else {
-                    let ptr: *mut *mut UnboxedVecRepr = cast::transmute(self);
+                    let ptr: *mut *mut Vec<()> = cast::transmute(self);
                     let alloc = n * sys::nonzero_size_of::<T>();
-                    let size = alloc + sys::size_of::<UnboxedVecRepr>();
+                    let size = alloc + sys::size_of::<Vec<()>>();
                     if alloc / sys::nonzero_size_of::<T>() != n || size < alloc {
                         fail!("vector size is too large: %u", n);
                     }
                     *ptr = realloc_raw(*ptr as *mut c_void, size)
-                           as *mut UnboxedVecRepr;
+                           as *mut Vec<()>;
                     (**ptr).alloc = alloc;
                 }
             }
@@ -1198,10 +1196,10 @@ impl<T> OwnedVector<T> for ~[T] {
     fn capacity(&self) -> uint {
         unsafe {
             if contains_managed::<T>() {
-                let repr: **raw::VecRepr = transmute(self);
-                (**repr).unboxed.alloc / sys::nonzero_size_of::<T>()
+                let repr: **Box<Vec<()>> = cast::transmute(self);
+                (**repr).data.alloc / sys::nonzero_size_of::<T>()
             } else {
-                let repr: **UnboxedVecRepr = transmute(self);
+                let repr: **Vec<()> = cast::transmute(self);
                 (**repr).alloc / sys::nonzero_size_of::<T>()
             }
         }
@@ -1212,16 +1210,16 @@ impl<T> OwnedVector<T> for ~[T] {
     fn push(&mut self, t: T) {
         unsafe {
             if contains_managed::<T>() {
-                let repr: **raw::VecRepr = transmute(&mut *self);
-                let fill = (**repr).unboxed.fill;
-                if (**repr).unboxed.alloc <= fill {
+                let repr: **Box<Vec<()>> = cast::transmute(&mut *self);
+                let fill = (**repr).data.fill;
+                if (**repr).data.alloc <= fill {
                     let new_len = self.len() + 1;
                     self.reserve_at_least(new_len);
                 }
 
                 self.push_fast(t);
             } else {
-                let repr: **UnboxedVecRepr = transmute(&mut *self);
+                let repr: **Vec<()> = cast::transmute(&mut *self);
                 let fill = (**repr).fill;
                 if (**repr).alloc <= fill {
                     let new_len = self.len() + 1;
@@ -1237,14 +1235,14 @@ impl<T> OwnedVector<T> for ~[T] {
     #[inline] // really pretty please
     unsafe fn push_fast(&mut self, t: T) {
         if contains_managed::<T>() {
-            let repr: **mut raw::VecRepr = transmute(self);
-            let fill = (**repr).unboxed.fill;
-            (**repr).unboxed.fill += sys::nonzero_size_of::<T>();
-            let p = to_unsafe_ptr(&((**repr).unboxed.data));
+            let repr: **mut Box<Vec<u8>> = cast::transmute(self);
+            let fill = (**repr).data.fill;
+            (**repr).data.fill += sys::nonzero_size_of::<T>();
+            let p = to_unsafe_ptr(&((**repr).data.data));
             let p = ptr::offset(p, fill) as *mut T;
             intrinsics::move_val_init(&mut(*p), t);
         } else {
-            let repr: **mut UnboxedVecRepr = transmute(self);
+            let repr: **mut Vec<u8> = cast::transmute(self);
             let fill = (**repr).fill;
             (**repr).fill += sys::nonzero_size_of::<T>();
             let p = to_unsafe_ptr(&((**repr).data));
@@ -1338,14 +1336,14 @@ impl<T> OwnedVector<T> for ~[T] {
             {
                 let first_slice = self.slice(0, 1);
                 let last_slice = self.slice(next_ln, ln);
-                raw::copy_memory(transmute(last_slice), first_slice, 1);
+                raw::copy_memory(cast::transmute(last_slice), first_slice, 1);
             }
 
             // Memcopy everything to the left one element
             {
                 let init_slice = self.slice(0, next_ln);
                 let tail_slice = self.slice(1, ln);
-                raw::copy_memory(transmute(init_slice),
+                raw::copy_memory(cast::transmute(init_slice),
                                  tail_slice,
                                  next_ln);
             }
@@ -1689,8 +1687,8 @@ pub trait MutableVector<'self, T> {
      */
     fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
 
-    unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T;
-    unsafe fn unsafe_set(&self, index: uint, val: T);
+    unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T;
+    unsafe fn unsafe_set(self, index: uint, val: T);
 
     fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U;
 }
@@ -1703,8 +1701,10 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
         assert!(end <= self.len());
         do self.as_mut_buf |p, _len| {
             unsafe {
-                transmute((ptr::mut_offset(p, start),
-                           (end - start) * sys::nonzero_size_of::<T>()))
+                cast::transmute(Slice {
+                    data: ptr::mut_offset(p, start) as *T,
+                    len: (end - start) * sys::nonzero_size_of::<T>()
+                })
             }
         }
     }
@@ -1723,8 +1723,8 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
         unsafe {
             let p = vec::raw::to_mut_ptr(self);
             VecMutIterator{ptr: p,
-                           end: cast::transmute(p as uint + self.len() *
-                                                sys::nonzero_size_of::<T>()),
+                           end: (p as uint + self.len() *
+                                 sys::nonzero_size_of::<T>()) as *mut T,
                            lifetime: cast::transmute(p)}
         }
     }
@@ -1771,22 +1771,20 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
     }
 
     #[inline]
-    unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T {
-        let pair_ptr: &(*mut T, uint) = transmute(self);
-        let (ptr, _) = *pair_ptr;
-        ptr.offset(index)
+    unsafe fn unsafe_mut_ref(self, index: uint) -> *mut T {
+        ptr::mut_offset(self.repr().data as *mut T, index)
     }
 
     #[inline]
-    unsafe fn unsafe_set(&self, index: uint, val: T) {
+    unsafe fn unsafe_set(self, index: uint, val: T) {
         *self.unsafe_mut_ref(index) = val;
     }
 
     /// Similar to `as_imm_buf` but passing a `*mut T`
     #[inline]
     fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U {
-        let (buf, len): (*mut T, uint) = unsafe { transmute(self) };
-        f(buf, len / sys::nonzero_size_of::<T>())
+        let Slice{ data, len } = self.repr();
+        f(data as *mut T, len / sys::nonzero_size_of::<T>())
     }
 
 }
@@ -1821,40 +1819,17 @@ pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
     raw::from_buf_raw(ptr, elts)
 }
 
-/// The internal 'unboxed' representation of a vector
-#[allow(missing_doc)]
-pub struct UnboxedVecRepr {
-    fill: uint,
-    alloc: uint,
-    data: u8
-}
-
 /// Unsafe operations
 pub mod raw {
-    use cast::transmute;
+    use cast;
     use clone::Clone;
-    use managed;
     use option::Some;
     use ptr;
     use sys;
     use unstable::intrinsics;
-    use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector};
+    use vec::{with_capacity, ImmutableVector, MutableVector};
     use unstable::intrinsics::contains_managed;
-
-    /// The internal representation of a (boxed) vector
-    #[allow(missing_doc)]
-    pub struct VecRepr {
-        box_header: managed::raw::BoxHeaderRepr,
-        unboxed: UnboxedVecRepr
-    }
-
-    /// The internal representation of a slice
-    pub struct SliceRepr {
-        /// Pointer to the base of this slice
-        data: *u8,
-        /// The length of the slice
-        len: uint
-    }
+    use unstable::raw::{Box, Vec, Slice};
 
     /**
      * Sets the length of a vector
@@ -1866,10 +1841,10 @@ pub mod raw {
     #[inline]
     pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
         if contains_managed::<T>() {
-            let repr: **mut VecRepr = transmute(v);
-            (**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
+            let repr: **mut Box<Vec<()>> = cast::transmute(v);
+            (**repr).data.fill = new_len * sys::nonzero_size_of::<T>();
         } else {
-            let repr: **mut UnboxedVecRepr = transmute(v);
+            let repr: **mut Vec<()> = cast::transmute(v);
             (**repr).fill = new_len * sys::nonzero_size_of::<T>();
         }
     }
@@ -1885,19 +1860,13 @@ pub mod raw {
      */
     #[inline]
     pub fn to_ptr<T>(v: &[T]) -> *T {
-        unsafe {
-            let repr: **SliceRepr = transmute(&v);
-            transmute(&((**repr).data))
-        }
+        v.repr().data
     }
 
     /** see `to_ptr()` */
     #[inline]
     pub fn to_mut_ptr<T>(v: &mut [T]) -> *mut T {
-        unsafe {
-            let repr: **SliceRepr = transmute(&v);
-            transmute(&((**repr).data))
-        }
+        v.repr().data as *mut T
     }
 
     /**
@@ -1908,9 +1877,10 @@ pub mod raw {
     pub unsafe fn buf_as_slice<T,U>(p: *T,
                                     len: uint,
                                     f: &fn(v: &[T]) -> U) -> U {
-        let pair = (p, len * sys::nonzero_size_of::<T>());
-        let v : *(&'blk [T]) = transmute(&pair);
-        f(*v)
+        f(cast::transmute(Slice {
+            data: p,
+            len: len * sys::nonzero_size_of::<T>()
+        }))
     }
 
     /**
@@ -1921,9 +1891,10 @@ pub mod raw {
     pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
                                         len: uint,
                                         f: &fn(v: &mut [T]) -> U) -> U {
-        let pair = (p, len * sys::nonzero_size_of::<T>());
-        let v : *(&'blk mut [T]) = transmute(&pair);
-        f(*v)
+        f(cast::transmute(Slice {
+            data: p as *T,
+            len: len * sys::nonzero_size_of::<T>()
+        }))
     }
 
     /**
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
index 6ec80140c76..10603751a06 100644
--- a/src/libsyntax/opt_vec.rs
+++ b/src/libsyntax/opt_vec.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 /*!
- *
  * Defines a type OptVec<T> that can be used in place of ~[T].
  * OptVec avoids the need for allocation for empty vectors.
  * OptVec implements the iterable interface as well as
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index bd57f123cc5..5cdf0ec1acc 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -384,12 +384,10 @@ mod test {
                               span:sp(0,6)})
     }
 
-    // FIXME (#6416): For some reason, this fails and causes a test failure, even though it's
-    // marked as `#[should_fail]`.
-    /*#[should_fail]
+    #[should_fail]
     #[test] fn bad_path_expr_1() {
         string_to_expr(@"::abc::def::return");
-    }*/
+    }
 
     #[test] fn string_to_tts_1 () {
         let (tts,_ps) = string_to_tts_and_sess(@"fn a (b : int) { b; }");
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index de97396e453..9d286f1759e 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -33,29 +33,46 @@ pub fn string_to_parser(source_str: @str) -> Parser {
     p
 }
 
+fn with_error_checking_parse<T>(s: @str, f: &fn(&mut Parser) -> T) -> T {
+    let mut p = string_to_parser(s);
+    let x = f(&mut p);
+    p.abort_if_errors();
+    x
+}
+
 pub fn string_to_crate (source_str : @str) -> @ast::Crate {
-    string_to_parser(source_str).parse_crate_mod()
+    do with_error_checking_parse(source_str) |p| {
+        p.parse_crate_mod()
+    }
 }
 
 // parse a string, return an expr
 pub fn string_to_expr (source_str : @str) -> @ast::expr {
-    string_to_parser(source_str).parse_expr()
+    do with_error_checking_parse(source_str) |p| {
+        p.parse_expr()
+    }
 }
 
 // parse a string, return an item
 pub fn string_to_item (source_str : @str) -> Option<@ast::item> {
-    string_to_parser(source_str).parse_item(~[])
+    do with_error_checking_parse(source_str) |p| {
+        p.parse_item(~[])
+    }
 }
 
 // parse a string, return an item and the ParseSess
 pub fn string_to_item_and_sess (source_str : @str) -> (Option<@ast::item>,@mut ParseSess) {
     let (p,ps) = string_to_parser_and_sess(source_str);
-    (p.parse_item(~[]),ps)
+    let io = p.parse_item(~[]);
+    p.abort_if_errors();
+    (io,ps)
 }
 
 // parse a string, return a stmt
 pub fn string_to_stmt(source_str : @str) -> @ast::stmt {
-    string_to_parser(source_str).parse_stmt(~[])
+    do with_error_checking_parse(source_str) |p| {
+        p.parse_stmt(~[])
+    }
 }
 
 // parse a string, return a pat. Uses "irrefutable"... which doesn't
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index a4afb1c0bc5..72979d67eef 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -152,8 +152,6 @@ cleanup_task(cleanup_args *args) {
 #endif
 }
 
-extern "C" CDECL void upcall_exchange_free(void *ptr);
-
 // This runs on the Rust stack
 void task_start_wrapper(spawn_args *a)
 {
diff --git a/src/snapshots.txt b/src/snapshots.txt
index a3297ef7f1d..495d58f06f3 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,3 +1,11 @@
+S 2013-07-25 4cf3072
+  macos-i386 f682d6e9ca0d56768bd36a0c05b7e58e12694dff
+  macos-x86_64 2f4e85c9756ba31a04fa8dd1c999fbaf8e1d3d1a
+  winnt-i386 6360e61fb5c432ad1511cb28af8e44cc0106f1aa
+  freebsd-x86_64 5e76c40a64b76e0a065d5b8d51c85dfe38ea833a
+  linux-i386 46961cef9d4efccf5df23a8389d63cf35d35c1d6
+  linux-x86_64 b416ca2644b14403818f0219673f6f8fe189e8b4
+
 S 2013-07-21 e336cbf
   macos-i386 d9666dccc1040ebe298a54acb378902a7472ad0f
   macos-x86_64 808f68916444e3857ef2aab20f8db9db8f4b0b4a
diff --git a/src/test/auxiliary/issue_3979_traits.rs b/src/test/auxiliary/issue_3979_traits.rs
index 1e56dab1559..eb10553f19c 100644
--- a/src/test/auxiliary/issue_3979_traits.rs
+++ b/src/test/auxiliary/issue_3979_traits.rs
@@ -14,12 +14,13 @@
 #[crate_type = "lib"];
 
 trait Positioned {
-  fn SetX(&self, int);
+  fn SetX(&mut self, int);
   fn X(&self) -> int;
 }
 
 trait Movable: Positioned {
-  fn translate(&self, dx: int) {
-    self.SetX(self.X() + dx);
+  fn translate(&mut self, dx: int) {
+    let x = self.X() + dx;
+    self.SetX(x);
   }
 }
diff --git a/src/test/auxiliary/no_std_crate.rs b/src/test/auxiliary/no_std_crate.rs
new file mode 100644
index 00000000000..70f1b76e246
--- /dev/null
+++ b/src/test/auxiliary/no_std_crate.rs
@@ -0,0 +1,3 @@
+#[no_std];
+
+pub fn foo() {}
diff --git a/src/test/compile-fail/issue-6804.rs b/src/test/compile-fail/issue-6804.rs
new file mode 100644
index 00000000000..0a62e889d09
--- /dev/null
+++ b/src/test/compile-fail/issue-6804.rs
@@ -0,0 +1,21 @@
+// Matching against NaN should result in a warning
+
+use std::float::NaN;
+
+fn main() {
+    let x = NaN;
+    match x {
+        NaN => {},
+        _ => {},
+    };
+    //~^^^ WARNING unmatchable NaN in pattern, use the is_NaN method in a guard instead
+    match [x, 1.0] {
+        [NaN, _] => {},
+        _ => {},
+    };
+    //~^^^ WARNING unmatchable NaN in pattern, use the is_NaN method in a guard instead
+}
+
+// At least one error is needed so that compilation fails
+#[static_assert]
+static b: bool = false; //~ ERROR static assertion failed
diff --git a/src/test/compile-fail/lint-default-methods.rs b/src/test/compile-fail/lint-default-methods.rs
deleted file mode 100644
index 23befde7559..00000000000
--- a/src/test/compile-fail/lint-default-methods.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#[forbid(default_methods)];
-
-trait Foo { //~ ERROR default methods are experimental
-    fn bar(&self) { println("hi"); }
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs
index 27c9ca64a93..2cabdfe5bb0 100644
--- a/src/test/compile-fail/lint-non-camel-case-types.rs
+++ b/src/test/compile-fail/lint-non-camel-case-types.rs
@@ -10,25 +10,25 @@
 
 #[forbid(non_camel_case_types)];
 
-struct foo { //~ ERROR type, variant, or trait should have a camel case identifier
+struct foo { //~ ERROR type `foo` should have a camel case identifier
     bar: int,
 }
 
-enum foo2 { //~ ERROR type, variant, or trait should have a camel case identifier
+enum foo2 { //~ ERROR type `foo2` should have a camel case identifier
     Bar
 }
 
-struct foo3 { //~ ERROR type, variant, or trait should have a camel case identifier
+struct foo3 { //~ ERROR type `foo3` should have a camel case identifier
     bar: int
 }
 
-type foo4 = int; //~ ERROR type, variant, or trait should have a camel case identifier
+type foo4 = int; //~ ERROR type `foo4` should have a camel case identifier
 
 enum Foo5 {
-    bar //~ ERROR type, variant, or trait should have a camel case identifier
+    bar //~ ERROR variant `bar` should have a camel case identifier
 }
 
-trait foo6 { //~ ERROR type, variant, or trait should have a camel case identifier
+trait foo6 { //~ ERROR trait `foo6` should have a camel case identifier
 }
 
 fn main() { }
diff --git a/src/test/run-pass/default-method-supertrait-vtable.rs b/src/test/run-pass/default-method-supertrait-vtable.rs
new file mode 100644
index 00000000000..90a2b914021
--- /dev/null
+++ b/src/test/run-pass/default-method-supertrait-vtable.rs
@@ -0,0 +1,36 @@
+// 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.
+
+
+// Tests that we can call a function bounded over a supertrait from
+// a default method
+
+fn require_y<T: Y>(x: T) -> int { x.y() }
+
+trait Y {
+    fn y(self) -> int;
+}
+
+
+trait Z: Y {
+    fn x(self) -> int {
+        require_y(self)
+    }
+}
+
+impl Y for int {
+    fn y(self) -> int { self }
+}
+
+impl Z for int;
+
+fn main() {
+    assert_eq!(12.x(), 12);
+}
diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs
index 2ee57624112..f2c5a7e94ef 100644
--- a/src/test/run-pass/deriving-zero.rs
+++ b/src/test/run-pass/deriving-zero.rs
@@ -33,6 +33,7 @@ struct Lots {
     g: (f32, char),
     h: ~[util::NonCopyable],
     i: @mut (int, int),
+    j: bool,
 }
 
 fn main() {
diff --git a/src/test/run-pass/enum-discr.rs b/src/test/run-pass/enum-discr.rs
new file mode 100644
index 00000000000..5a14f0050e8
--- /dev/null
+++ b/src/test/run-pass/enum-discr.rs
@@ -0,0 +1,20 @@
+enum Animal {
+    Cat = 0u,
+    Dog = 1u,
+    Horse = 2u,
+    Snake = 3u
+}
+
+enum Hero {
+    Batman = -1,
+    Superman = -2,
+    Ironman = -3,
+    Spiderman = -4
+}
+
+fn main() {
+    let pet: Animal = Snake;
+    let hero: Hero = Superman;
+    assert!(pet as uint == 3);
+    assert!(hero as int == -2);
+}
diff --git a/src/test/run-pass/issue-3168.rs b/src/test/run-pass/issue-3168.rs
index fbe66708e47..609849bffb4 100644
--- a/src/test/run-pass/issue-3168.rs
+++ b/src/test/run-pass/issue-3168.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // xfail-fast
+// xfail-win32 #7999
 
 use std::comm;
 use std::task;
diff --git a/src/test/run-pass/issue-3176.rs b/src/test/run-pass/issue-3176.rs
index 96648a2706b..df242ee3d30 100644
--- a/src/test/run-pass/issue-3176.rs
+++ b/src/test/run-pass/issue-3176.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // xfail-fast
+// xfail-win32 #7999
 
 use std::comm::{Select2, Selectable};
 use std::comm;
diff --git a/src/test/run-pass/issue-3979-2.rs b/src/test/run-pass/issue-3979-2.rs
index 9a8b90db185..39e9f5dcd2d 100644
--- a/src/test/run-pass/issue-3979-2.rs
+++ b/src/test/run-pass/issue-3979-2.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test
-
 trait A {
     fn a_method(&self);
 }
diff --git a/src/test/run-pass/issue-3979-generics.rs b/src/test/run-pass/issue-3979-generics.rs
index 2a1ded96827..867301121da 100644
--- a/src/test/run-pass/issue-3979-generics.rs
+++ b/src/test/run-pass/issue-3979-generics.rs
@@ -8,15 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test FIXME #5946
 trait Positioned<S> {
   fn SetX(&mut self, S);
   fn X(&self) -> S;
 }
 
-trait Movable<S, T>: Positioned<T> {
-  fn translate(&self, dx: T) {
-    self.SetX(self.X() + dx);
+trait Movable<S: Add<S, S>>: Positioned<S> {
+  fn translate(&mut self, dx: S) {
+    let x = self.X() + dx;
+    self.SetX(x);
   }
 }
 
@@ -31,10 +31,10 @@ impl Positioned<int> for Point {
     }
 }
 
-impl Movable<int, int> for Point;
+impl Movable<int> for Point;
 
 pub fn main() {
-    let p = Point{ x: 1, y: 2};
+    let mut p = Point{ x: 1, y: 2};
     p.translate(3);
     assert_eq!(p.X(), 4);
 }
diff --git a/src/test/run-pass/issue-3979-xcrate.rs b/src/test/run-pass/issue-3979-xcrate.rs
index 4bde414c4ac..caf6d202316 100644
--- a/src/test/run-pass/issue-3979-xcrate.rs
+++ b/src/test/run-pass/issue-3979-xcrate.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test // tjc: ???
+// xfail-fast
 // aux-build:issue_3979_traits.rs
 extern mod issue_3979_traits;
 use issue_3979_traits::*;
diff --git a/src/test/run-pass/issue-3979.rs b/src/test/run-pass/issue-3979.rs
index fe10dd5af53..2e53fb5d3f9 100644
--- a/src/test/run-pass/issue-3979.rs
+++ b/src/test/run-pass/issue-3979.rs
@@ -1,5 +1,3 @@
-// xfail-test
-// Reason: ICE with explicit self
 
 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
diff --git a/src/test/run-pass/issue-7712.rs b/src/test/run-pass/issue-7712.rs
index d4faae415d2..41c4af86bac 100644
--- a/src/test/run-pass/issue-7712.rs
+++ b/src/test/run-pass/issue-7712.rs
@@ -10,8 +10,6 @@
 
 // compile-flags:-Z debug-info
 
-#[allow(default_methods)];
-
 pub trait TraitWithDefaultMethod {
     pub fn method(self) {
         ()
@@ -24,4 +22,4 @@ impl TraitWithDefaultMethod for MyStruct { }
 
 fn main() {
     MyStruct.method();
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/issue-2467.rs b/src/test/run-pass/no-std-xcrate.rs
index 3149db8a03f..104e33b7488 100644
--- a/src/test/compile-fail/issue-2467.rs
+++ b/src/test/run-pass/no-std-xcrate.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -8,9 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum test { thing = 3u } //~ ERROR mismatched types
-//~^ ERROR expected signed integer constant
+// xfail-fast
+// aux-build:no_std_crate.rs
+
+// This tests that crates which link to std can also be linked to crates with
+// #[no_std] that have no lang items.
+
+extern mod no_std_crate;
+
 fn main() {
-    error!(thing as int);
-    assert_eq!(thing as int, 3);
+    no_std_crate::foo();
 }
diff --git a/src/test/run-pass/no-std-xcrate2.rs b/src/test/run-pass/no-std-xcrate2.rs
new file mode 100644
index 00000000000..e393eb3a5c9
--- /dev/null
+++ b/src/test/run-pass/no-std-xcrate2.rs
@@ -0,0 +1,35 @@
+// 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.
+
+// xfail-test: this has weird linking problems on linux, and it probably needs a
+//             solution along the lines of disabling segmented stacks and/or the
+//             stack checks.
+// aux-build:no_std_crate.rs
+
+// This tests that libraries built with #[no_std] can be linked to crates with
+// #[no_std] and actually run.
+
+#[no_std];
+
+extern mod no_std_crate;
+
+// This is an unfortunate thing to have to do on linux :(
+#[cfg(target_os = "linux")]
+#[doc(hidden)]
+pub mod linkhack {
+    #[link_args="-lrustrt -lrt"]
+    extern {}
+}
+
+#[start]
+fn main(_: int, _: **u8, _: *u8) -> int {
+    no_std_crate::foo();
+    0
+}
diff --git a/src/test/run-pass/pipe-sleep.rs b/src/test/run-pass/pipe-sleep.rs
index 549c7332440..4475a16a63b 100644
--- a/src/test/run-pass/pipe-sleep.rs
+++ b/src/test/run-pass/pipe-sleep.rs
@@ -11,6 +11,7 @@
 // except according to those terms.
 
 // xfail-test needs sleep
+// xfail-win32 #7999
 
 extern mod extra;
 
diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs
index 21d13c722e7..e91537bec3b 100644
--- a/src/test/run-pass/reflect-visit-data.rs
+++ b/src/test/run-pass/reflect-visit-data.rs
@@ -14,8 +14,8 @@ use std::int;
 use std::libc::c_void;
 use std::ptr;
 use std::sys;
-use std::vec::UnboxedVecRepr;
 use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
+use std::unstable::raw::Vec;
 
 #[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
 
@@ -247,7 +247,7 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
     }
 
     fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
-        self.align_to::<UnboxedVecRepr>();
+        self.align_to::<Vec<()>>();
         // FIXME (#3732): Inner really has to move its own pointers on this one.
         // or else possibly we could have some weird interface wherein we
         // read-off a word from inner's pointers, but the read-word has to
diff --git a/src/test/run-pass/supertrait-default-generics.rs b/src/test/run-pass/supertrait-default-generics.rs
new file mode 100644
index 00000000000..ae7e18d532b
--- /dev/null
+++ b/src/test/run-pass/supertrait-default-generics.rs
@@ -0,0 +1,42 @@
+// 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.
+
+// There is some other borrowck bug, so we make the stuff not mut.
+
+trait Positioned<S> {
+  fn SetX(&mut self, S);
+  fn X(&self) -> S;
+}
+
+trait Movable<S: Add<S, S>>: Positioned<S> {
+  fn translate(&mut self, dx: S) {
+    let x = self.X() + dx;
+    self.SetX(x);
+  }
+}
+
+struct Point<S> { x: S, y: S }
+
+impl<S: Clone> Positioned<S> for Point<S> {
+    fn SetX(&mut self, x: S) {
+        self.x = x;
+    }
+    fn X(&self) -> S {
+        self.x.clone()
+    }
+}
+
+impl<S: Clone + Add<S, S>> Movable<S> for Point<S>;
+
+pub fn main() {
+    let mut p = Point{ x: 1, y: 2};
+    p.translate(3);
+    assert_eq!(p.X(), 4);
+}
diff --git a/src/test/compile-fail/tag-variant-disr-type-mismatch.rs b/src/test/run-pass/tag-variant-disr-type-mismatch.rs
index 518a12fb2eb..514f868db54 100644
--- a/src/test/compile-fail/tag-variant-disr-type-mismatch.rs
+++ b/src/test/run-pass/tag-variant-disr-type-mismatch.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//error-pattern: mismatched types
-
 enum color {
     red = 1u,
     blue = 2,
diff --git a/src/test/run-pass/unit-like-struct-drop-run.rs b/src/test/run-pass/unit-like-struct-drop-run.rs
index 41b971d64d0..d4a95ea607c 100644
--- a/src/test/run-pass/unit-like-struct-drop-run.rs
+++ b/src/test/run-pass/unit-like-struct-drop-run.rs
@@ -10,6 +10,7 @@
 
 // Make sure the destructor is run for unit-like structs.
 // xfail-fast
+// xfail-win32 #7999
 
 use std::task;