about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiletest/compiletest.rs3
-rw-r--r--src/doc/guide.md28
-rw-r--r--src/doc/reference.md8
-rw-r--r--src/driver/driver.rs2
-rw-r--r--src/etc/gdb_rust_pretty_printing.py16
-rw-r--r--src/etc/licenseck.py5
-rw-r--r--src/etc/lldb_rust_formatters.py9
-rwxr-xr-xsrc/etc/unicode.py16
-rw-r--r--src/liballoc/arc.rs6
-rw-r--r--src/liballoc/boxed.rs3
-rw-r--r--src/liballoc/heap.rs61
-rw-r--r--src/liballoc/rc.rs11
-rw-r--r--src/libcollections/btree/set.rs66
-rw-r--r--src/libcollections/str.rs6
-rw-r--r--src/libcollections/trie/set.rs126
-rw-r--r--src/libcollections/vec_map.rs16
-rw-r--r--src/libcore/any.rs3
-rw-r--r--src/libcore/borrow.rs12
-rw-r--r--src/libcore/cell.rs121
-rw-r--r--src/libcore/char.rs3
-rw-r--r--src/libcore/cmp.rs10
-rw-r--r--src/libcore/fmt/float.rs2
-rw-r--r--src/libcore/fmt/mod.rs6
-rw-r--r--src/libcore/intrinsics.rs2
-rw-r--r--src/libcore/iter.rs60
-rw-r--r--src/libcore/num/mod.rs11
-rw-r--r--src/libcore/ops.rs52
-rw-r--r--src/libcore/option.rs3
-rw-r--r--src/libcore/ptr.rs7
-rw-r--r--src/libcore/result.rs3
-rw-r--r--src/libcore/slice.rs14
-rw-r--r--src/libcore/str.rs9
-rw-r--r--src/libcore/tuple/mod.rs3
-rw-r--r--src/libcoretest/num/mod.rs3
-rw-r--r--src/libfmt_macros/lib.rs5
-rw-r--r--src/libgetopts/lib.rs20
-rw-r--r--src/librbml/lib.rs6
-rw-r--r--src/librustc/lib.rs3
-rw-r--r--src/librustc/lint/builtin.rs15
-rw-r--r--src/librustc/lint/context.rs40
-rw-r--r--src/librustc/metadata/csearch.rs3
-rw-r--r--src/librustc/metadata/decoder.rs3
-rw-r--r--src/librustc/middle/astconv_util.rs89
-rw-r--r--src/librustc/middle/astencode.rs79
-rw-r--r--src/librustc/middle/cfg/construct.rs5
-rw-r--r--src/librustc/middle/check_const.rs3
-rw-r--r--src/librustc/middle/check_static.rs4
-rw-r--r--src/librustc/middle/const_eval.rs14
-rw-r--r--src/librustc/middle/dead.rs12
-rw-r--r--src/librustc/middle/effect.rs2
-rw-r--r--src/librustc/middle/expr_use_visitor.rs9
-rw-r--r--src/librustc/middle/infer/coercion.rs (renamed from src/librustc/middle/typeck/infer/coercion.rs)9
-rw-r--r--src/librustc/middle/infer/combine.rs (renamed from src/librustc/middle/typeck/infer/combine.rs)17
-rw-r--r--src/librustc/middle/infer/doc.rs (renamed from src/librustc/middle/typeck/infer/doc.rs)0
-rw-r--r--src/librustc/middle/infer/equate.rs (renamed from src/librustc/middle/typeck/infer/equate.rs)16
-rw-r--r--src/librustc/middle/infer/error_reporting.rs (renamed from src/librustc/middle/typeck/infer/error_reporting.rs)27
-rw-r--r--src/librustc/middle/infer/glb.rs (renamed from src/librustc/middle/typeck/infer/glb.rs)16
-rw-r--r--src/librustc/middle/infer/higher_ranked/doc.rs (renamed from src/librustc/middle/typeck/infer/higher_ranked/doc.rs)0
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs (renamed from src/librustc/middle/typeck/infer/higher_ranked/mod.rs)17
-rw-r--r--src/librustc/middle/infer/lattice.rs (renamed from src/librustc/middle/typeck/infer/lattice.rs)9
-rw-r--r--src/librustc/middle/infer/lub.rs (renamed from src/librustc/middle/typeck/infer/lub.rs)17
-rw-r--r--src/librustc/middle/infer/mod.rs (renamed from src/librustc/middle/typeck/infer/mod.rs)0
-rw-r--r--src/librustc/middle/infer/region_inference/doc.rs (renamed from src/librustc/middle/typeck/infer/region_inference/doc.rs)2
-rw-r--r--src/librustc/middle/infer/region_inference/mod.rs (renamed from src/librustc/middle/typeck/infer/region_inference/mod.rs)8
-rw-r--r--src/librustc/middle/infer/resolve.rs (renamed from src/librustc/middle/typeck/infer/resolve.rs)5
-rw-r--r--src/librustc/middle/infer/skolemize.rs (renamed from src/librustc/middle/typeck/infer/skolemize.rs)0
-rw-r--r--src/librustc/middle/infer/sub.rs (renamed from src/librustc/middle/typeck/infer/sub.rs)18
-rw-r--r--src/librustc/middle/infer/type_variable.rs (renamed from src/librustc/middle/typeck/infer/type_variable.rs)0
-rw-r--r--src/librustc/middle/infer/unify.rs (renamed from src/librustc/middle/typeck/infer/unify.rs)4
-rw-r--r--src/librustc/middle/liveness.rs4
-rw-r--r--src/librustc/middle/mem_categorization.rs15
-rw-r--r--src/librustc/middle/privacy.rs4
-rw-r--r--src/librustc/middle/reachable.rs5
-rw-r--r--src/librustc/middle/resolve.rs39
-rw-r--r--src/librustc/middle/subst.rs3
-rw-r--r--src/librustc/middle/traits/coherence.rs2
-rw-r--r--src/librustc/middle/traits/fulfill.rs2
-rw-r--r--src/librustc/middle/traits/mod.rs2
-rw-r--r--src/librustc/middle/traits/select.rs4
-rw-r--r--src/librustc/middle/traits/util.rs2
-rw-r--r--src/librustc/middle/ty.rs235
-rw-r--r--src/librustc/middle/ty_fold.rs41
-rw-r--r--src/librustc/session/config.rs53
-rw-r--r--src/librustc/util/ppaux.rs37
-rw-r--r--src/librustc_driver/driver.rs (renamed from src/librustc_trans/driver/driver.rs)144
-rw-r--r--src/librustc_driver/lib.rs (renamed from src/librustc_trans/driver/mod.rs)78
-rw-r--r--src/librustc_driver/mod.rs10
-rw-r--r--src/librustc_driver/pretty.rs (renamed from src/librustc_trans/driver/pretty.rs)26
-rw-r--r--src/librustc_driver/test.rs (renamed from src/librustc_trans/test.rs)36
-rw-r--r--src/librustc_trans/back/link.rs8
-rw-r--r--src/librustc_trans/back/write.rs4
-rw-r--r--src/librustc_trans/lib.rs10
-rw-r--r--src/librustc_trans/save/mod.rs17
-rw-r--r--src/librustc_trans/trans/base.rs20
-rw-r--r--src/librustc_trans/trans/cabi.rs4
-rw-r--r--src/librustc_trans/trans/callee.rs5
-rw-r--r--src/librustc_trans/trans/common.rs14
-rw-r--r--src/librustc_trans/trans/context.rs4
-rw-r--r--src/librustc_trans/trans/controlflow.rs2
-rw-r--r--src/librustc_trans/trans/datum.rs7
-rw-r--r--src/librustc_trans/trans/expr.rs18
-rw-r--r--src/librustc_trans/trans/meth.rs11
-rw-r--r--src/librustc_trans/trans/mod.rs98
-rw-r--r--src/librustc_typeck/astconv.rs (renamed from src/librustc/middle/typeck/astconv.rs)86
-rw-r--r--src/librustc_typeck/check/_match.rs (renamed from src/librustc/middle/typeck/check/_match.rs)8
-rw-r--r--src/librustc_typeck/check/closure.rs (renamed from src/librustc/middle/typeck/check/closure.rs)6
-rw-r--r--src/librustc_typeck/check/demand.rs (renamed from src/librustc/middle/typeck/check/demand.rs)25
-rw-r--r--src/librustc_typeck/check/method/confirm.rs (renamed from src/librustc/middle/typeck/check/method/confirm.rs)9
-rw-r--r--src/librustc_typeck/check/method/doc.rs (renamed from src/librustc/middle/typeck/check/method/doc.rs)0
-rw-r--r--src/librustc_typeck/check/method/mod.rs (renamed from src/librustc/middle/typeck/check/method/mod.rs)14
-rw-r--r--src/librustc_typeck/check/method/probe.rs (renamed from src/librustc/middle/typeck/check/method/probe.rs)10
-rw-r--r--src/librustc_typeck/check/mod.rs (renamed from src/librustc/middle/typeck/check/mod.rs)86
-rw-r--r--src/librustc_typeck/check/regionck.rs (renamed from src/librustc/middle/typeck/check/regionck.rs)17
-rw-r--r--src/librustc_typeck/check/regionmanip.rs (renamed from src/librustc/middle/typeck/check/regionmanip.rs)19
-rw-r--r--src/librustc_typeck/check/vtable.rs (renamed from src/librustc/middle/typeck/check/vtable.rs)32
-rw-r--r--src/librustc_typeck/check/wf.rs (renamed from src/librustc/middle/typeck/check/wf.rs)6
-rw-r--r--src/librustc_typeck/check/writeback.rs (renamed from src/librustc/middle/typeck/check/writeback.rs)17
-rw-r--r--src/librustc_typeck/coherence/mod.rs (renamed from src/librustc/middle/typeck/coherence/mod.rs)32
-rw-r--r--src/librustc_typeck/coherence/orphan.rs (renamed from src/librustc/middle/typeck/coherence/orphan.rs)0
-rw-r--r--src/librustc_typeck/coherence/overlap.rs (renamed from src/librustc/middle/typeck/coherence/overlap.rs)3
-rw-r--r--src/librustc_typeck/collect.rs (renamed from src/librustc/middle/typeck/collect.rs)27
-rw-r--r--src/librustc_typeck/diagnostics.rs151
-rw-r--r--src/librustc_typeck/lib.rs (renamed from src/librustc/middle/typeck/mod.rs)248
-rw-r--r--src/librustc_typeck/rscope.rs (renamed from src/librustc/middle/typeck/rscope.rs)0
-rw-r--r--src/librustc_typeck/variance.rs (renamed from src/librustc/middle/typeck/variance.rs)0
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/core.rs6
-rw-r--r--src/librustdoc/html/format.rs3
-rw-r--r--src/librustdoc/html/item_type.rs101
-rw-r--r--src/librustdoc/html/layout.rs3
-rw-r--r--src/librustdoc/html/render.rs149
-rw-r--r--src/librustdoc/html/static/main.js11
-rw-r--r--src/librustdoc/lib.rs7
-rw-r--r--src/librustdoc/test.rs6
-rw-r--r--src/libstd/ascii.rs3
-rw-r--r--src/libstd/bitflags.rs6
-rw-r--r--src/libstd/c_vec.rs3
-rw-r--r--src/libstd/collections/hash/map.rs6
-rw-r--r--src/libstd/collections/hash/set.rs4
-rw-r--r--src/libstd/collections/hash/table.rs3
-rw-r--r--src/libstd/collections/lru_cache.rs5
-rw-r--r--src/libstd/comm/mod.rs20
-rw-r--r--src/libstd/comm/mpsc_queue.rs (renamed from src/libstd/sync/mpsc_queue.rs)9
-rw-r--r--src/libstd/comm/shared.rs21
-rw-r--r--src/libstd/comm/spsc_queue.rs (renamed from src/libstd/sync/spsc_queue.rs)160
-rw-r--r--src/libstd/comm/stream.rs2
-rw-r--r--src/libstd/dynamic_lib.rs7
-rw-r--r--src/libstd/error.rs3
-rw-r--r--src/libstd/failure.rs5
-rw-r--r--src/libstd/fmt.rs2
-rw-r--r--src/libstd/io/buffered.rs5
-rw-r--r--src/libstd/io/comm_adapters.rs4
-rw-r--r--src/libstd/io/extensions.rs5
-rw-r--r--src/libstd/io/fs.rs37
-rw-r--r--src/libstd/io/mem.rs54
-rw-r--r--src/libstd/io/mod.rs14
-rw-r--r--src/libstd/io/net/addrinfo.rs3
-rw-r--r--src/libstd/io/net/ip.rs5
-rw-r--r--src/libstd/io/net/mod.rs4
-rw-r--r--src/libstd/io/net/tcp.rs5
-rw-r--r--src/libstd/io/net/udp.rs2
-rw-r--r--src/libstd/io/result.rs2
-rw-r--r--src/libstd/io/stdio.rs157
-rw-r--r--src/libstd/io/tempfile.rs5
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/os.rs37
-rw-r--r--src/libstd/path/mod.rs3
-rw-r--r--src/libstd/path/posix.rs3
-rw-r--r--src/libstd/path/windows.rs3
-rw-r--r--src/libstd/rand/mod.rs2
-rw-r--r--src/libstd/rand/os.rs6
-rw-r--r--src/libstd/rand/reader.rs2
-rw-r--r--src/libstd/rt/backtrace.rs29
-rw-r--r--src/libstd/rt/util.rs3
-rw-r--r--src/libstd/sync/barrier.rs116
-rw-r--r--src/libstd/sync/condvar.rs365
-rw-r--r--src/libstd/sync/deque.rs663
-rw-r--r--src/libstd/sync/future.rs2
-rw-r--r--src/libstd/sync/lock.rs805
-rw-r--r--src/libstd/sync/mod.rs44
-rw-r--r--src/libstd/sync/mpmc_bounded_queue.rs219
-rw-r--r--src/libstd/sync/mutex.rs364
-rw-r--r--src/libstd/sync/once.rs (renamed from src/libstd/sync/one.rs)17
-rw-r--r--src/libstd/sync/poison.rs48
-rw-r--r--src/libstd/sync/raw.rs1132
-rw-r--r--src/libstd/sync/rwlock.rs514
-rw-r--r--src/libstd/sync/semaphore.rs195
-rw-r--r--src/libstd/sys/common/condvar.rs67
-rw-r--r--src/libstd/sys/common/helper_thread.rs21
-rw-r--r--src/libstd/sys/common/mod.rs5
-rw-r--r--src/libstd/sys/common/mutex.rs64
-rw-r--r--src/libstd/sys/common/net.rs12
-rw-r--r--src/libstd/sys/common/rwlock.rs86
-rw-r--r--src/libstd/sys/unix/condvar.rs83
-rw-r--r--src/libstd/sys/unix/fs.rs2
-rw-r--r--src/libstd/sys/unix/mod.rs10
-rw-r--r--src/libstd/sys/unix/mutex.rs52
-rw-r--r--src/libstd/sys/unix/pipe.rs7
-rw-r--r--src/libstd/sys/unix/process.rs43
-rw-r--r--src/libstd/sys/unix/rwlock.rs57
-rw-r--r--src/libstd/sys/unix/sync.rs208
-rw-r--r--src/libstd/sys/windows/condvar.rs63
-rw-r--r--src/libstd/sys/windows/ext.rs4
-rw-r--r--src/libstd/sys/windows/fs.rs2
-rw-r--r--src/libstd/sys/windows/mod.rs8
-rw-r--r--src/libstd/sys/windows/mutex.rs78
-rw-r--r--src/libstd/sys/windows/pipe.rs7
-rw-r--r--src/libstd/sys/windows/rwlock.rs53
-rw-r--r--src/libstd/sys/windows/sync.rs58
-rw-r--r--src/libstd/sys/windows/tcp.rs40
-rw-r--r--src/libstd/task.rs18
-rw-r--r--src/libstd/thread_local/mod.rs6
-rw-r--r--src/libstd/time/duration.rs8
-rw-r--r--src/libsyntax/diagnostics/plugin.rs37
-rw-r--r--src/libsyntax/ext/build.rs8
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs7
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs6
-rw-r--r--src/libsyntax/ext/env.rs2
-rw-r--r--src/libsyntax/ext/quote.rs3
-rw-r--r--src/libsyntax/feature_gate.rs25
-rw-r--r--src/libsyntax/parse/attr.rs2
-rw-r--r--src/libsyntax/parse/common.rs7
-rw-r--r--src/libsyntax/parse/lexer/mod.rs81
-rw-r--r--src/libsyntax/parse/mod.rs22
-rw-r--r--src/libsyntax/parse/parser.rs188
-rw-r--r--src/libterm/terminfo/parm.rs2
-rw-r--r--src/libtest/lib.rs93
-rw-r--r--src/libtest/stats.rs12
-rw-r--r--src/libtime/lib.rs2
-rw-r--r--src/libunicode/normalize.rs5
-rw-r--r--src/libunicode/tables.rs16
-rw-r--r--src/libunicode/u_str.rs3
-rw-r--r--src/snapshots.txt9
-rw-r--r--src/test/bench/msgsend-ring-mutex-arcs.rs16
-rw-r--r--src/test/bench/msgsend-ring-rw-arcs.rs113
-rw-r--r--src/test/bench/shootout-k-nucleotide-pipes.rs8
-rw-r--r--src/test/bench/shootout-k-nucleotide.rs2
-rw-r--r--src/test/bench/shootout-pfib.rs2
-rw-r--r--src/test/bench/sudoku.rs4
-rw-r--r--src/test/compile-fail/better-expected.rs (renamed from src/test/compile-fail/rustc-diagnostics-2.rs)9
-rw-r--r--src/test/compile-fail/borrow-tuple-fields.rs2
-rw-r--r--src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs2
-rw-r--r--src/test/compile-fail/column-offset-1-based.rs2
-rw-r--r--src/test/compile-fail/empty-impl-semicolon.rs2
-rw-r--r--src/test/compile-fail/if-let.rs2
-rw-r--r--src/test/compile-fail/issue-1655.rs2
-rw-r--r--src/test/compile-fail/issue-18566.rs2
-rw-r--r--src/test/compile-fail/issue-18959.rs (renamed from src/test/compile-fail/rustc-diagnostics-1.rs)26
-rw-r--r--src/test/compile-fail/issue-19096.rs2
-rw-r--r--src/test/compile-fail/issue-19244-1.rs2
-rw-r--r--src/test/compile-fail/issue-19498.rs21
-rw-r--r--src/test/compile-fail/issue-3036.rs2
-rw-r--r--src/test/compile-fail/issue-5806.rs4
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs3
-rw-r--r--src/test/compile-fail/lint-unnecessary-parens.rs1
-rw-r--r--src/test/compile-fail/lint-unused-imports.rs4
-rw-r--r--src/test/compile-fail/match-vec-invalid.rs2
-rw-r--r--src/test/compile-fail/move-fragments-1.rs2
-rw-r--r--src/test/compile-fail/move-out-of-tuple-field.rs2
-rw-r--r--src/test/compile-fail/multitrait.rs2
-rw-r--r--src/test/compile-fail/mut-patterns.rs2
-rw-r--r--src/test/compile-fail/new-unicode-escapes-1.rs (renamed from src/test/compile-fail/rustc-diagnostics-3.rs)11
-rw-r--r--src/test/compile-fail/new-unicode-escapes-2.rs13
-rw-r--r--src/test/compile-fail/new-unicode-escapes-3.rs13
-rw-r--r--src/test/compile-fail/new-unicode-escapes-4.rs13
-rw-r--r--src/test/compile-fail/omitted-arg-in-item-fn.rs2
-rw-r--r--src/test/compile-fail/pat-range-bad-dots.rs2
-rw-r--r--src/test/compile-fail/raw-str-unbalanced.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-closure-lifetime.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-enum-newtype.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-fixed-vec.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-larrow-init.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-larrow-move.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-mut-vec-expr.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-mut-vec-ty.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-ptr-lifetime.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-record.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-uniq-mut-expr.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-uniq-mut-ty.rs2
-rw-r--r--src/test/compile-fail/removed-syntax-with-1.rs2
-rw-r--r--src/test/compile-fail/struct-literal-in-for.rs2
-rw-r--r--src/test/compile-fail/struct-literal-in-if.rs2
-rw-r--r--src/test/compile-fail/struct-literal-in-match-discriminant.rs2
-rw-r--r--src/test/compile-fail/struct-literal-in-while.rs2
-rw-r--r--src/test/compile-fail/trailing-comma-array-repeat.rs (renamed from src/test/compile-fail/issue-17718-extern-const.rs)6
-rw-r--r--src/test/compile-fail/tuple-index-not-tuple.rs2
-rw-r--r--src/test/compile-fail/tuple-index-out-of-bounds.rs2
-rw-r--r--src/test/compile-fail/unresolved-extern-mod-suggestion.rs3
-rw-r--r--src/test/compile-fail/while-let.rs2
-rw-r--r--src/test/debuginfo/gdb-pretty-struct-and-enums.rs12
-rw-r--r--src/test/debuginfo/option-like-enum.rs9
-rw-r--r--src/test/run-fail/result-get-panic.rs4
-rw-r--r--src/test/run-make/issue-19371/foo.rs8
-rw-r--r--src/test/run-pass/deriving-cmp-shortcircuit.rs2
-rw-r--r--src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs2
-rw-r--r--src/test/run-pass/enum-nullable-const-null-with-fields.rs3
-rw-r--r--src/test/run-pass/issue-13304.rs2
-rw-r--r--src/test/run-pass/issue-14456.rs2
-rw-r--r--src/test/run-pass/issue-16671.rs4
-rw-r--r--src/test/run-pass/issue-2804.rs6
-rw-r--r--src/test/run-pass/issue-3424.rs2
-rw-r--r--src/test/run-pass/new-unicode-escapes.rs22
-rw-r--r--src/test/run-pass/nullable-pointer-iotareduction.rs4
-rw-r--r--src/test/run-pass/send_str_hashmap.rs2
-rw-r--r--src/test/run-pass/send_str_treemap.rs2
-rw-r--r--src/test/run-pass/trailing-comma.rs6
-rw-r--r--src/test/run-pass/wait-forked-but-failed-child.rs80
307 files changed, 5433 insertions, 5045 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index f76cefcd941..e28029c4d9d 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -286,6 +286,9 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
         test_shard: config.test_shard.clone(),
         nocapture: false,
         color: test::AutoColor,
+        show_boxplot: false,
+        boxplot_width: 50,
+        show_all_stats: false,
     }
 }
 
diff --git a/src/doc/guide.md b/src/doc/guide.md
index c2d43a20ec4..3f3b533bbd5 100644
--- a/src/doc/guide.md
+++ b/src/doc/guide.md
@@ -140,7 +140,7 @@ $ editor main.rs
 ```
 
 Rust files always end in a `.rs` extension. If you're using more than one word
-in your file name, use an underscore. `hello_world.rs` rather than
+in your filename, use an underscore. `hello_world.rs` rather than
 `helloworld.rs`.
 
 Now that you've got your file open, type this in:
@@ -200,7 +200,7 @@ about this difference. Just know that sometimes, you'll see a `!`, and that
 means that you're calling a macro instead of a normal function. Rust implements
 `println!` as a macro rather than a function for good reasons, but that's a
 very advanced topic. You'll learn more when we talk about macros later. One
-last thing to mention: Rust's macros are significantly different than C macros,
+last thing to mention: Rust's macros are significantly different from C macros,
 if you've used those. Don't be scared of using macros. We'll get to the details
 eventually, you'll just have to trust us for now.
 
@@ -595,8 +595,8 @@ let y = if x == 5i { 10i } else { 15i };
 ```
 
 This reveals two interesting things about Rust: it is an expression-based
-language, and semicolons are different than in other 'curly brace and
-semicolon'-based languages. These two things are related.
+language, and semicolons are different from semicolons in other 'curly brace
+and semicolon'-based languages. These two things are related.
 
 ## Expressions vs. Statements
 
@@ -1454,7 +1454,7 @@ Both `continue` and `break` are valid in both kinds of loops.
 # Strings
 
 Strings are an important concept for any programmer to master. Rust's string
-handling system is a bit different than in other languages, due to its systems
+handling system is a bit different from other languages, due to its systems
 focus. Any time you have a data structure of variable size, things can get
 tricky, and strings are a re-sizable data structure. That said, Rust's strings
 also work differently than in some other systems languages, such as C.
@@ -2064,8 +2064,8 @@ Great! Next up: let's compare our guess to the secret guess.
 ## Comparing guesses
 
 If you remember, earlier in the guide, we made a `cmp` function that compared
-two numbers. Let's add that in, along with a `match` statement to compare the
-guess to the secret guess:
+two numbers. Let's add that in, along with a `match` statement to compare our
+guess to the secret number:
 
 ```{rust,ignore}
 use std::io;
@@ -2861,7 +2861,7 @@ parts of your library. The six levels are:
 * experimental: This item was only recently introduced or is otherwise in a
   state of flux. It may change significantly, or even be removed. No guarantee
   of backwards-compatibility.
-* unstable: This item is still under development, but requires more testing to
+* unstable: This item is still under development and requires more testing to
   be considered stable. No guarantee of backwards-compatibility.
 * stable: This item is considered stable, and will not change significantly.
   Guarantee of backwards-compatibility.
@@ -5174,12 +5174,12 @@ processor. Rust's semantics lend themselves very nicely to solving a number of
 issues that programmers have with concurrency. Many concurrency errors that are
 runtime errors in other languages are compile-time errors in Rust.
 
-Rust's concurrency primitive is called a **task**. Tasks are lightweight, and
-do not share memory in an unsafe manner, preferring message passing to
-communicate.  It's worth noting that tasks are implemented as a library, and
-not part of the language.  This means that in the future, other concurrency
-libraries can be written for Rust to help in specific scenarios.  Here's an
-example of creating a task:
+Rust's concurrency primitive is called a **task**. Tasks are similar to
+threads, and do not share memory in an unsafe manner, preferring message
+passing to communicate. It's worth noting that tasks are implemented as a
+library, and not part of the language. This means that in the future, other
+concurrency libraries can be written for Rust to help in specific scenarios.
+Here's an example of creating a task:
 
 ```{rust}
 spawn(proc() {
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 1d27ac096df..9ac4469d549 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -522,7 +522,7 @@ The two values of the boolean type are written `true` and `false`.
 ### Symbols
 
 ```{.ebnf .gram}
-symbol : "::" "->"
+symbol : "::" | "->"
        | '#' | '[' | ']' | '(' | ')' | '{' | '}'
        | ',' | ';' ;
 ```
@@ -994,7 +994,7 @@ An example of `use` declarations:
 
 ```
 use std::iter::range_step;
-use std::option::{Some, None};
+use std::option::Option::{Some, None};
 use std::collections::hash_map::{mod, HashMap};
 
 fn foo<T>(_: T){}
@@ -1004,8 +1004,8 @@ fn main() {
     // Equivalent to 'std::iter::range_step(0u, 10u, 2u);'
     range_step(0u, 10u, 2u);
 
-    // Equivalent to 'foo(vec![std::option::Some(1.0f64),
-    // std::option::None]);'
+    // Equivalent to 'foo(vec![std::option::Option::Some(1.0f64),
+    // std::option::Option::None]);'
     foo(vec![Some(1.0f64), None]);
 
     // Both `hash_map` and `HashMap` are in scope.
diff --git a/src/driver/driver.rs b/src/driver/driver.rs
index 632d21d7b9c..5c29cb4ec72 100644
--- a/src/driver/driver.rs
+++ b/src/driver/driver.rs
@@ -12,6 +12,6 @@
 extern crate "rustdoc" as this;
 
 #[cfg(rustc)]
-extern crate "rustc_trans" as this;
+extern crate "rustc_driver" as this;
 
 fn main() { this::main() }
diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py
index 1af649f0731..7e5918ea39e 100644
--- a/src/etc/gdb_rust_pretty_printing.py
+++ b/src/etc/gdb_rust_pretty_printing.py
@@ -54,13 +54,14 @@ def rust_pretty_printer_lookup_function(val):
       return RustStructPrinter(val, false)
 
     if enum_member_count == 1:
-      if enum_members[0].name == None:
+      first_variant_name = enum_members[0].name
+      if first_variant_name == None:
         # This is a singleton enum
         return rust_pretty_printer_lookup_function(val[enum_members[0]])
       else:
-        assert enum_members[0].name.startswith("RUST$ENCODED$ENUM$")
+        assert first_variant_name.startswith("RUST$ENCODED$ENUM$")
         # This is a space-optimized enum
-        last_separator_index = enum_members[0].name.rfind("$")
+        last_separator_index = first_variant_name.rfind("$")
         second_last_separator_index = first_variant_name.rfind("$", 0, last_separator_index)
         disr_field_index = first_variant_name[second_last_separator_index + 1 :
                                               last_separator_index]
@@ -68,7 +69,12 @@ def rust_pretty_printer_lookup_function(val):
 
         sole_variant_val = val[enum_members[0]]
         disr_field = get_field_at_index(sole_variant_val, disr_field_index)
-        discriminant = int(sole_variant_val[disr_field])
+        discriminant = sole_variant_val[disr_field]
+
+        # If the discriminant field is a fat pointer we have to consider the
+        # first word as the true discriminant
+        if discriminant.type.code == gdb.TYPE_CODE_STRUCT:
+            discriminant = discriminant[get_field_at_index(discriminant, 0)]
 
         if discriminant == 0:
           null_variant_name = first_variant_name[last_separator_index + 1:]
@@ -173,7 +179,7 @@ class RustCStyleEnumPrinter:
 
 class IdentityPrinter:
   def __init__(self, string):
-    self.string
+    self.string = string
 
   def to_string(self):
     return self.string
diff --git a/src/etc/licenseck.py b/src/etc/licenseck.py
index 9162edcb530..7669df36b04 100644
--- a/src/etc/licenseck.py
+++ b/src/etc/licenseck.py
@@ -38,9 +38,8 @@ exceptions = [
     "rt/isaac/randport.cpp", # public domain
     "rt/isaac/rand.h", # public domain
     "rt/isaac/standard.h", # public domain
-    "libstd/sync/mpsc_queue.rs", # BSD
-    "libstd/sync/spsc_queue.rs", # BSD
-    "libstd/sync/mpmc_bounded_queue.rs", # BSD
+    "libstd/comm/mpsc_queue.rs", # BSD
+    "libstd/comm/spsc_queue.rs", # BSD
     "test/bench/shootout-binarytrees.rs", # BSD
     "test/bench/shootout-chameneos-redux.rs", # BSD
     "test/bench/shootout-fannkuch-redux.rs", # BSD
diff --git a/src/etc/lldb_rust_formatters.py b/src/etc/lldb_rust_formatters.py
index 7924d63c8e0..f4f1a5121d1 100644
--- a/src/etc/lldb_rust_formatters.py
+++ b/src/etc/lldb_rust_formatters.py
@@ -138,9 +138,14 @@ def print_enum_val(val, internal_dict):
         return "<invalid enum encoding: %s>" % first_variant_name
 
       # Read the discriminant
-      disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index).GetValueAsUnsigned()
+      disr_val = val.GetChildAtIndex(0).GetChildAtIndex(disr_field_index)
 
-      if disr_val == 0:
+      # If the discriminant field is a fat pointer we have to consider the
+      # first word as the true discriminant
+      if disr_val.GetType().GetTypeClass() == lldb.eTypeClassStruct:
+          disr_val = disr_val.GetChildAtIndex(0)
+
+      if disr_val.GetValueAsUnsigned() == 0:
         # Null case: Print the name of the null-variant
         null_variant_name = first_variant_name[last_separator_index + 1:]
         return null_variant_name
diff --git a/src/etc/unicode.py b/src/etc/unicode.py
index 15263919fb9..20edf9418f1 100755
--- a/src/etc/unicode.py
+++ b/src/etc/unicode.py
@@ -292,7 +292,7 @@ def escape_char(c):
 def emit_bsearch_range_table(f):
     f.write("""
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
-    use core::cmp::{Equal, Less, Greater};
+    use core::cmp::Ordering::{Equal, Less, Greater};
     use core::slice::SlicePrelude;
     r.binary_search(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
@@ -350,10 +350,11 @@ def emit_regex_module(f, cats, w_data):
 def emit_conversions_module(f, lowerupper, upperlower):
     f.write("pub mod conversions {")
     f.write("""
-    use core::cmp::{Equal, Less, Greater};
+    use core::cmp::Ordering::{Equal, Less, Greater};
     use core::slice::SlicePrelude;
     use core::tuple::Tuple2;
-    use core::option::{Option, Some, None};
+    use core::option::Option;
+    use core::option::Option::{Some, None};
     use core::slice;
 
     pub fn to_lower(c: char) -> char {
@@ -403,7 +404,7 @@ def emit_grapheme_module(f, grapheme_table, grapheme_cats):
     f.write("""    }
 
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
-        use core::cmp::{Equal, Less, Greater};
+        use core::cmp::Ordering::{Equal, Less, Greater};
         match r.binary_search(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
@@ -430,12 +431,13 @@ def emit_grapheme_module(f, grapheme_table, grapheme_cats):
 
 def emit_charwidth_module(f, width_table):
     f.write("pub mod charwidth {\n")
-    f.write("    use core::option::{Option, Some, None};\n")
+    f.write("    use core::option::Option;\n")
+    f.write("    use core::option::Option::{Some, None};\n")
     f.write("    use core::slice::SlicePrelude;\n")
     f.write("    use core::slice;\n")
     f.write("""
     fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
-        use core::cmp::{Equal, Less, Greater};
+        use core::cmp::Ordering::{Equal, Less, Greater};
         match r.binary_search(|&(lo, hi, _, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
@@ -530,7 +532,7 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
 
     f.write("""
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
-        use core::cmp::{Equal, Less, Greater};
+        use core::cmp::Ordering::{Equal, Less, Greater};
         use core::slice::SlicePrelude;
         use core::slice;
         match r.binary_search(|&(lo, hi, _)| {
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 4f744b0b2de..ef05279e825 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -22,7 +22,8 @@ use core::kinds::{Sync, Send};
 use core::mem::{min_align_of, size_of, drop};
 use core::mem;
 use core::ops::{Drop, Deref};
-use core::option::{Some, None, Option};
+use core::option::Option;
+use core::option::Option::{Some, None};
 use core::ptr::RawPtr;
 use core::ptr;
 use heap::deallocate;
@@ -326,7 +327,8 @@ mod tests {
     use std::comm::channel;
     use std::mem::drop;
     use std::ops::Drop;
-    use std::option::{Option, Some, None};
+    use std::option::Option;
+    use std::option::Option::{Some, None};
     use std::str::Str;
     use std::sync::atomic;
     use std::task;
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 000dda59e3d..eb483498998 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -19,7 +19,8 @@ use core::kinds::Sized;
 use core::mem;
 use core::option::Option;
 use core::raw::TraitObject;
-use core::result::{Ok, Err, Result};
+use core::result::Result;
+use core::result::Result::{Ok, Err};
 
 /// A value that represents the global exchange heap. This is the default
 /// place that the `box` keyword allocates into when no place is supplied.
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index 579f47ee874..c6b6a784f06 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -123,9 +123,62 @@ const MIN_ALIGN: uint = 8;
           target_arch = "x86_64"))]
 const MIN_ALIGN: uint = 16;
 
-#[cfg(jemalloc)]
+#[cfg(external_funcs)]
 mod imp {
-    use core::option::{None, Option};
+    extern {
+        fn rust_allocate(size: uint, align: uint) -> *mut u8;
+        fn rust_deallocate(ptr: *mut u8, old_size: uint, align: uint);
+        fn rust_reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8;
+        fn rust_reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint,
+                                   align: uint) -> uint;
+        fn rust_usable_size(size: uint, align: uint) -> uint;
+        fn rust_stats_print();
+    }
+
+    #[inline]
+    pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
+        rust_allocate(size, align)
+    }
+
+    #[inline]
+    pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint,
+                                     align: uint) -> uint {
+        rust_reallocate_inplace(ptr, old_size, size, align)
+    }
+
+    #[inline]
+    pub unsafe fn deallocate(ptr: *mut u8, old_size: uint, align: uint) {
+        rust_deallocate(ptr, old_size, align)
+    }
+
+    #[inline]
+    pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint,
+                                     align: uint) -> uint {
+        rust_reallocate_inplace(ptr, old_size, size, align)
+    }
+
+    #[inline]
+    pub fn usable_size(size: uint, align: uint) -> uint {
+        unsafe { rust_usable_size(size, align) }
+    }
+
+    #[inline]
+    pub fn stats_print() {
+        unsafe { rust_stats_print() }
+    }
+}
+
+#[cfg(external_crate)]
+mod imp {
+    extern crate external;
+    pub use self::external::{allocate, deallocate, reallocate_inplace, reallocate};
+    pub use self::external::{usable_size, stats_print};
+}
+
+#[cfg(all(not(external_funcs), not(external_crate), jemalloc))]
+mod imp {
+    use core::option::Option;
+    use core::option::Option::None;
     use core::ptr::{null_mut, null};
     use core::num::Int;
     use libc::{c_char, c_int, c_void, size_t};
@@ -199,7 +252,7 @@ mod imp {
     }
 }
 
-#[cfg(all(not(jemalloc), unix))]
+#[cfg(all(not(external_funcs), not(external_crate), not(jemalloc), unix))]
 mod imp {
     use core::cmp;
     use core::ptr;
@@ -260,7 +313,7 @@ mod imp {
     pub fn stats_print() {}
 }
 
-#[cfg(all(not(jemalloc), windows))]
+#[cfg(all(not(external_funcs), not(external_crate), not(jemalloc), windows))]
 mod imp {
     use libc::{c_void, size_t};
     use libc;
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index e626d63937b..53891583edb 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -149,10 +149,12 @@ use core::fmt;
 use core::kinds::marker;
 use core::mem::{transmute, min_align_of, size_of, forget};
 use core::ops::{Deref, Drop};
-use core::option::{Option, Some, None};
+use core::option::Option;
+use core::option::Option::{Some, None};
 use core::ptr;
 use core::ptr::RawPtr;
-use core::result::{Result, Ok, Err};
+use core::result::Result;
+use core::result::Result::{Ok, Err};
 
 use heap::deallocate;
 
@@ -739,8 +741,9 @@ impl<T> RcBoxPtr<T> for Weak<T> {
 mod tests {
     use super::{Rc, Weak, weak_count, strong_count};
     use std::cell::RefCell;
-    use std::option::{Option, Some, None};
-    use std::result::{Err, Ok};
+    use std::option::Option;
+    use std::option::Option::{Some, None};
+    use std::result::Result::{Err, Ok};
     use std::mem::drop;
     use std::clone::Clone;
 
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 64ae4f6a508..3973b4774b3 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -94,12 +94,46 @@ impl<T> BTreeSet<T> {
 
 impl<T: Ord> BTreeSet<T> {
     /// Visits the values representing the difference, in ascending order.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut a = BTreeSet::new();
+    /// a.insert(1u);
+    /// a.insert(2u);
+    ///
+    /// let mut b = BTreeSet::new();
+    /// b.insert(2u);
+    /// b.insert(3u);
+    ///
+    /// let diff: Vec<uint> = a.difference(&b).cloned().collect();
+    /// assert_eq!(diff, vec![1u]);
+    /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn difference<'a>(&'a self, other: &'a BTreeSet<T>) -> DifferenceItems<'a, T> {
         DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
     }
 
     /// Visits the values representing the symmetric difference, in ascending order.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut a = BTreeSet::new();
+    /// a.insert(1u);
+    /// a.insert(2u);
+    ///
+    /// let mut b = BTreeSet::new();
+    /// b.insert(2u);
+    /// b.insert(3u);
+    ///
+    /// let sym_diff: Vec<uint> = a.symmetric_difference(&b).cloned().collect();
+    /// assert_eq!(sym_diff, vec![1u,3]);
+    /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn symmetric_difference<'a>(&'a self, other: &'a BTreeSet<T>)
         -> SymDifferenceItems<'a, T> {
@@ -107,6 +141,23 @@ impl<T: Ord> BTreeSet<T> {
     }
 
     /// Visits the values representing the intersection, in ascending order.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut a = BTreeSet::new();
+    /// a.insert(1u);
+    /// a.insert(2u);
+    ///
+    /// let mut b = BTreeSet::new();
+    /// b.insert(2u);
+    /// b.insert(3u);
+    ///
+    /// let intersection: Vec<uint> = a.intersection(&b).cloned().collect();
+    /// assert_eq!(intersection, vec![2u]);
+    /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T>)
         -> IntersectionItems<'a, T> {
@@ -114,6 +165,21 @@ impl<T: Ord> BTreeSet<T> {
     }
 
     /// Visits the values representing the union, in ascending order.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut a = BTreeSet::new();
+    /// a.insert(1u);
+    ///
+    /// let mut b = BTreeSet::new();
+    /// b.insert(2u);
+    ///
+    /// let union: Vec<uint> = a.union(&b).cloned().collect();
+    /// assert_eq!(union, vec![1u,2]);
+    /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn union<'a>(&'a self, other: &'a BTreeSet<T>) -> UnionItems<'a, T> {
         UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index ad0a5e76176..78cdda61104 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -833,8 +833,10 @@ mod tests {
     use std::default::Default;
     use std::char::Char;
     use std::clone::Clone;
-    use std::cmp::{Equal, Greater, Less, Ord, PartialOrd, Equiv};
-    use std::option::{Some, None};
+    use std::cmp::{Ord, PartialOrd, Equiv};
+    use std::cmp::Ordering::{Equal, Greater, Less};
+    use std::option::Option;
+    use std::option::Option::{Some, None};
     use std::ptr::RawPtr;
     use std::iter::{Iterator, IteratorExt, DoubleEndedIteratorExt};
 
diff --git a/src/libcollections/trie/set.rs b/src/libcollections/trie/set.rs
index dd884b6ee41..1b3657943da 100644
--- a/src/libcollections/trie/set.rs
+++ b/src/libcollections/trie/set.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // FIXME(conventions): implement bounded iterators
-// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub
 // FIXME(conventions): replace each_reverse by making iter DoubleEnded
 // FIXME(conventions): implement iter_mut and into_iter
 
@@ -463,6 +462,90 @@ impl Extend<uint> for TrieSet {
     }
 }
 
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl BitOr<TrieSet, TrieSet> for TrieSet {
+    /// Returns the union of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TrieSet = a | b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![1u, 2, 3, 4, 5]);
+    /// ```
+    fn bitor(&self, rhs: &TrieSet) -> TrieSet {
+        self.union(rhs).collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl BitAnd<TrieSet, TrieSet> for TrieSet {
+    /// Returns the intersection of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set: TrieSet = a & b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![2u, 3]);
+    /// ```
+    fn bitand(&self, rhs: &TrieSet) -> TrieSet {
+        self.intersection(rhs).collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl BitXor<TrieSet, TrieSet> for TrieSet {
+    /// Returns the symmetric difference of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TrieSet = a ^ b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![1u, 2, 4, 5]);
+    /// ```
+    fn bitxor(&self, rhs: &TrieSet) -> TrieSet {
+        self.symmetric_difference(rhs).collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl Sub<TrieSet, TrieSet> for TrieSet {
+    /// Returns the difference of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TrieSet = a - b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![1u, 2]);
+    /// ```
+    fn sub(&self, rhs: &TrieSet) -> TrieSet {
+        self.difference(rhs).collect()
+    }
+}
+
 /// A forward iterator over a set.
 pub struct SetItems<'a> {
     iter: Entries<'a, ()>
@@ -569,6 +652,7 @@ impl<'a> Iterator<uint> for UnionItems<'a> {
 mod test {
     use std::prelude::*;
     use std::uint;
+    use vec::Vec;
 
     use super::TrieSet;
 
@@ -738,4 +822,44 @@ mod test {
                     &[1, 5, 9, 13, 19],
                     &[1, 3, 5, 9, 11, 13, 16, 19, 24]);
     }
+
+    #[test]
+    fn test_bit_or() {
+        let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+        let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+
+        let set: TrieSet = a | b;
+        let v: Vec<uint> = set.iter().collect();
+        assert_eq!(v, vec![1u, 2, 3, 4, 5]);
+    }
+
+    #[test]
+    fn test_bit_and() {
+        let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+        let b: TrieSet = vec![2, 3, 4].into_iter().collect();
+
+        let set: TrieSet = a & b;
+        let v: Vec<uint> = set.iter().collect();
+        assert_eq!(v, vec![2u, 3]);
+    }
+
+    #[test]
+    fn test_bit_xor() {
+        let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+        let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+
+        let set: TrieSet = a ^ b;
+        let v: Vec<uint> = set.iter().collect();
+        assert_eq!(v, vec![1u, 2, 4, 5]);
+    }
+
+    #[test]
+    fn test_sub() {
+        let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+        let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+
+        let set: TrieSet = a - b;
+        let v: Vec<uint> = set.iter().collect();
+        assert_eq!(v, vec![1u, 2]);
+    }
 }
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 36e66ed27f3..986e7ef5bc2 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -115,6 +115,22 @@ impl<V> VecMap<V> {
         VecMap { v: Vec::with_capacity(capacity) }
     }
 
+    /// Returns the number of elements the `VecMap` can hold without
+    /// reallocating.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::VecMap;
+    /// let map: VecMap<String> = VecMap::with_capacity(10);
+    /// assert!(map.capacity() >= 10);
+    /// ```
+    #[inline]
+    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    pub fn capacity(&self) -> uint {
+        self.v.capacity()
+    }
+
     /// Returns an iterator visiting all keys in ascending order by the keys.
     /// The iterator's element type is `uint`.
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 5d1f996831e..75feb4d8828 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -72,7 +72,8 @@
 #![stable]
 
 use mem::{transmute};
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use raw::TraitObject;
 use intrinsics::TypeId;
 
diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs
index b88fb914dd8..b44b87bd938 100644
--- a/src/libcore/borrow.rs
+++ b/src/libcore/borrow.rs
@@ -137,6 +137,18 @@ pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
     Owned(T)
 }
 
+impl<'a, T, Sized? B> Clone for Cow<'a, T, B> where B: ToOwned<T> {
+    fn clone(&self) -> Cow<'a, T, B> {
+        match *self {
+            Borrowed(b) => Borrowed(b),
+            Owned(ref o) => {
+                let b: &B = BorrowFrom::borrow_from(o);
+                Owned(b.to_owned())
+            },
+        }
+    }
+}
+
 impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned<T> {
     /// Acquire a mutable reference to the owned form of the data.
     ///
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 587bb4cb110..1ec2efaf801 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -160,7 +160,8 @@ use cmp::PartialEq;
 use default::Default;
 use kinds::{marker, Copy};
 use ops::{Deref, DerefMut, Drop};
-use option::{None, Option, Some};
+use option::Option;
+use option::Option::{None, Some};
 
 /// A mutable memory location that admits only `Copy` data.
 #[unstable = "likely to be renamed; otherwise stable"]
@@ -277,12 +278,9 @@ impl<T> RefCell<T> {
     /// Returns `None` if the value is currently mutably borrowed.
     #[unstable = "may be renamed, depending on global conventions"]
     pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
-        match self.borrow.get() {
-            WRITING => None,
-            borrow => {
-                self.borrow.set(borrow + 1);
-                Some(Ref { _parent: self })
-            }
+        match BorrowRef::new(&self.borrow) {
+            Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }),
+            None => None,
         }
     }
 
@@ -310,12 +308,9 @@ impl<T> RefCell<T> {
     /// Returns `None` if the value is currently borrowed.
     #[unstable = "may be renamed, depending on global conventions"]
     pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
-        match self.borrow.get() {
-            UNUSED => {
-                self.borrow.set(WRITING);
-                Some(RefMut { _parent: self })
-            },
-            _ => None
+        match BorrowRefMut::new(&self.borrow) {
+            Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }),
+            None => None,
         }
     }
 
@@ -368,29 +363,56 @@ impl<T: PartialEq> PartialEq for RefCell<T> {
     }
 }
 
-/// Wraps a borrowed reference to a value in a `RefCell` box.
-#[unstable]
-pub struct Ref<'b, T:'b> {
-    // FIXME #12808: strange name to try to avoid interfering with
-    // field accesses of the contained type via Deref
-    _parent: &'b RefCell<T>
+struct BorrowRef<'b> {
+    _borrow: &'b Cell<BorrowFlag>,
+}
+
+impl<'b> BorrowRef<'b> {
+    fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
+        match borrow.get() {
+            WRITING => None,
+            b => {
+                borrow.set(b + 1);
+                Some(BorrowRef { _borrow: borrow })
+            },
+        }
+    }
 }
 
 #[unsafe_destructor]
-#[unstable]
-impl<'b, T> Drop for Ref<'b, T> {
+impl<'b> Drop for BorrowRef<'b> {
     fn drop(&mut self) {
-        let borrow = self._parent.borrow.get();
+        let borrow = self._borrow.get();
         debug_assert!(borrow != WRITING && borrow != UNUSED);
-        self._parent.borrow.set(borrow - 1);
+        self._borrow.set(borrow - 1);
     }
 }
 
+impl<'b> Clone for BorrowRef<'b> {
+    fn clone(&self) -> BorrowRef<'b> {
+        // Since this Ref exists, we know the borrow flag
+        // is not set to WRITING.
+        let borrow = self._borrow.get();
+        debug_assert!(borrow != WRITING && borrow != UNUSED);
+        self._borrow.set(borrow + 1);
+        BorrowRef { _borrow: self._borrow }
+    }
+}
+
+/// Wraps a borrowed reference to a value in a `RefCell` box.
+#[unstable]
+pub struct Ref<'b, T:'b> {
+    // FIXME #12808: strange name to try to avoid interfering with
+    // field accesses of the contained type via Deref
+    _value: &'b T,
+    _borrow: BorrowRef<'b>,
+}
+
 #[unstable = "waiting for `Deref` to become stable"]
 impl<'b, T> Deref<T> for Ref<'b, T> {
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
-        unsafe { &*self._parent.value.get() }
+        self._value
     }
 }
 
@@ -401,41 +423,52 @@ impl<'b, T> Deref<T> for Ref<'b, T> {
 /// A `Clone` implementation would interfere with the widespread
 /// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
 #[experimental = "likely to be moved to a method, pending language changes"]
-pub fn clone_ref<'b, T>(orig: &Ref<'b, T>) -> Ref<'b, T> {
-    // Since this Ref exists, we know the borrow flag
-    // is not set to WRITING.
-    let borrow = orig._parent.borrow.get();
-    debug_assert!(borrow != WRITING && borrow != UNUSED);
-    orig._parent.borrow.set(borrow + 1);
-
+pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> {
     Ref {
-        _parent: orig._parent,
+        _value: orig._value,
+        _borrow: orig._borrow.clone(),
     }
 }
 
-/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
-#[unstable]
-pub struct RefMut<'b, T:'b> {
-    // FIXME #12808: strange name to try to avoid interfering with
-    // field accesses of the contained type via Deref
-    _parent: &'b RefCell<T>
+struct BorrowRefMut<'b> {
+    _borrow: &'b Cell<BorrowFlag>,
 }
 
 #[unsafe_destructor]
-#[unstable]
-impl<'b, T> Drop for RefMut<'b, T> {
+impl<'b> Drop for BorrowRefMut<'b> {
     fn drop(&mut self) {
-        let borrow = self._parent.borrow.get();
+        let borrow = self._borrow.get();
         debug_assert!(borrow == WRITING);
-        self._parent.borrow.set(UNUSED);
+        self._borrow.set(UNUSED);
     }
 }
 
+impl<'b> BorrowRefMut<'b> {
+    fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
+        match borrow.get() {
+            UNUSED => {
+                borrow.set(WRITING);
+                Some(BorrowRefMut { _borrow: borrow })
+            },
+            _ => None,
+        }
+    }
+}
+
+/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
+#[unstable]
+pub struct RefMut<'b, T:'b> {
+    // FIXME #12808: strange name to try to avoid interfering with
+    // field accesses of the contained type via Deref
+    _value: &'b mut T,
+    _borrow: BorrowRefMut<'b>,
+}
+
 #[unstable = "waiting for `Deref` to become stable"]
 impl<'b, T> Deref<T> for RefMut<'b, T> {
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
-        unsafe { &*self._parent.value.get() }
+        self._value
     }
 }
 
@@ -443,7 +476,7 @@ impl<'b, T> Deref<T> for RefMut<'b, T> {
 impl<'b, T> DerefMut<T> for RefMut<'b, T> {
     #[inline]
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
-        unsafe { &mut *self._parent.value.get() }
+        self._value
     }
 }
 
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index a729596e9d2..2bebe87a14c 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -16,7 +16,8 @@
 #![doc(primitive = "char")]
 
 use mem::transmute;
-use option::{None, Option, Some};
+use option::Option;
+use option::Option::{None, Some};
 use iter::{range_step, Iterator, RangeStep};
 use slice::SlicePrelude;
 
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index df19256471e..a5ba2b03b15 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -44,7 +44,8 @@
 pub use self::Ordering::*;
 
 use kinds::Sized;
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 
 /// Trait for values that can be compared for equality and inequality.
 ///
@@ -288,10 +289,11 @@ pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 
 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
 mod impls {
-    use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
-              Less, Greater, Equal};
+    use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering};
+    use cmp::Ordering::{Less, Greater, Equal};
     use kinds::Sized;
-    use option::{Option, Some, None};
+    use option::Option;
+    use option::Option::{Some, None};
 
     macro_rules! partial_eq_impl(
         ($($t:ty)*) => ($(
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index 1e31df83779..400ce76baa0 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -20,7 +20,7 @@ use fmt;
 use iter::{range, DoubleEndedIteratorExt};
 use num::{Float, FPNaN, FPInfinite, ToPrimitive};
 use num::cast;
-use result::Ok;
+use result::Result::Ok;
 use slice::{mod, SlicePrelude};
 use str::StrPrelude;
 
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 1d6906c13a8..9b67cdd3e12 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -17,9 +17,10 @@ use cell::{Cell, Ref, RefMut};
 use iter::{Iterator, IteratorExt, range};
 use kinds::{Copy, Sized};
 use mem;
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use ops::Deref;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use result;
 use slice::SlicePrelude;
 use slice;
@@ -34,6 +35,7 @@ mod float;
 pub mod rt;
 
 #[experimental = "core and I/O reconciliation may alter this definition"]
+/// The type returned by formatter methods.
 pub type Result = result::Result<(), Error>;
 
 /// The error type which is returned from formatting a message into a stream.
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 347777b587a..ece2ac6975e 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -10,7 +10,7 @@
 
 //! rustc compiler intrinsics.
 //!
-//! The corresponding definitions are in librustc/middle/trans/foreign.rs.
+//! The corresponding definitions are in librustc_trans/trans/intrinsic.rs.
 //!
 //! # Volatiles
 //!
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index f9595f0663d..49865bd3c7d 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -62,7 +62,8 @@ use cmp::Ord;
 use mem;
 use num::{ToPrimitive, Int};
 use ops::{Add, Deref};
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use uint;
 
 #[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;
@@ -2036,18 +2037,49 @@ for Inspect<'a, A, T> {
     }
 }
 
-/// An iterator which just modifies the contained state throughout iteration.
+/// An iterator which passes mutable state to a closure and yields the result.
+///
+/// # Example: The Fibonacci Sequence
+///
+/// An iterator that yields sequential Fibonacci numbers, and stops on overflow.
+///
+/// ```rust
+/// use std::iter::Unfold;
+/// use std::num::Int; // For `.checked_add()`
+///
+/// // This iterator will yield up to the last Fibonacci number before the max value of `u32`.
+/// // You can simply change `u32` to `u64` in this line if you want higher values than that.
+/// let mut fibonacci = Unfold::new((Some(0u32), Some(1u32)), |&(ref mut x2, ref mut x1)| {
+///     // Attempt to get the next Fibonacci number
+///     // `x1` will be `None` if previously overflowed.
+///     let next = match (*x2, *x1) {
+///         (Some(x2), Some(x1)) => x2.checked_add(x1),
+///         _ => None,
+///     };
+///
+///     // Shift left: ret <- x2 <- x1 <- next
+///     let ret = *x2;
+///     *x2 = *x1;
+///     *x1 = next;
+///
+///     ret
+/// });
+///
+/// for i in fibonacci {
+///     println!("{}", i);
+/// }
+/// ```
 #[experimental]
 pub struct Unfold<'a, A, St> {
     f: |&mut St|: 'a -> Option<A>,
-    /// Internal state that will be yielded on the next iteration
+    /// Internal state that will be passed to the closure on the next iteration
     pub state: St,
 }
 
 #[experimental]
 impl<'a, A, St> Unfold<'a, A, St> {
     /// Creates a new iterator with the specified closure as the "iterator
-    /// function" and an initial state to eventually pass to the iterator
+    /// function" and an initial state to eventually pass to the closure
     #[inline]
     pub fn new<'a>(initial_state: St, f: |&mut St|: 'a -> Option<A>)
                -> Unfold<'a, A, St> {
@@ -2427,7 +2459,9 @@ pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
 pub mod order {
     use cmp;
     use cmp::{Eq, Ord, PartialOrd, PartialEq};
-    use option::{Option, Some, None};
+    use cmp::Ordering::{Equal, Less, Greater};
+    use option::Option;
+    use option::Option::{Some, None};
     use super::Iterator;
 
     /// Compare `a` and `b` for equality using `Eq`
@@ -2445,11 +2479,11 @@ pub mod order {
     pub fn cmp<A: Ord, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S) -> cmp::Ordering {
         loop {
             match (a.next(), b.next()) {
-                (None, None) => return cmp::Equal,
-                (None, _   ) => return cmp::Less,
-                (_   , None) => return cmp::Greater,
+                (None, None) => return Equal,
+                (None, _   ) => return Less,
+                (_   , None) => return Greater,
                 (Some(x), Some(y)) => match x.cmp(&y) {
-                    cmp::Equal => (),
+                    Equal => (),
                     non_eq => return non_eq,
                 },
             }
@@ -2461,11 +2495,11 @@ pub mod order {
             -> Option<cmp::Ordering> {
         loop {
             match (a.next(), b.next()) {
-                (None, None) => return Some(cmp::Equal),
-                (None, _   ) => return Some(cmp::Less),
-                (_   , None) => return Some(cmp::Greater),
+                (None, None) => return Some(Equal),
+                (None, _   ) => return Some(Less),
+                (_   , None) => return Some(Greater),
                 (Some(x), Some(y)) => match x.partial_cmp(&y) {
-                    Some(cmp::Equal) => (),
+                    Some(Equal) => (),
                     non_eq => return non_eq,
                 },
             }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index ce61bd97e13..e6946c83ceb 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -30,7 +30,8 @@ use kinds::Copy;
 use mem::size_of;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use str::{FromStr, from_str, StrPrelude};
 
 /// Simultaneous division and remainder
@@ -284,7 +285,7 @@ pub trait Int
     /// ```
     fn checked_add(self, other: Self) -> Option<Self>;
 
-    /// Checked integer subtraction. Computes `self + other`, returning `None`
+    /// Checked integer subtraction. Computes `self - other`, returning `None`
     /// if underflow occurred.
     ///
     /// # Example
@@ -297,7 +298,7 @@ pub trait Int
     /// ```
     fn checked_sub(self, other: Self) -> Option<Self>;
 
-    /// Checked integer multiplication. Computes `self + other`, returning
+    /// Checked integer multiplication. Computes `self * other`, returning
     /// `None` if underflow or overflow occurred.
     ///
     /// # Example
@@ -310,8 +311,8 @@ pub trait Int
     /// ```
     fn checked_mul(self, other: Self) -> Option<Self>;
 
-    /// Checked integer division. Computes `self + other` returning `None` if
-    /// `self == 0` or the operation results in underflow or overflow.
+    /// Checked integer division. Computes `self / other`, returning `None` if
+    /// `other == 0` or the operation results in underflow or overflow.
     ///
     /// # Example
     ///
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 4f4ec486797..ce774a66381 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -787,7 +787,7 @@ impl<'a, Sized? T> Deref<T> for &'a mut T {
 /// }
 /// ```
 #[lang="deref_mut"]
-pub trait DerefMut<Sized? Result>: Deref<Result> {
+pub trait DerefMut<Sized? Result> for Sized? : Deref<Result> {
     /// The method called to mutably dereference a value
     fn deref_mut<'a>(&'a mut self) -> &'a mut Result;
 }
@@ -832,53 +832,3 @@ impl<F,A,R> FnOnce<A,R> for F
         self.call_mut(args)
     }
 }
-
-#[cfg(stage0)]
-mod fn_impls {
-    use super::Fn;
-
-    impl<Result> Fn<(),Result> for extern "Rust" fn() -> Result {
-        #[allow(non_snake_case)]
-        extern "rust-call" fn call(&self, _args: ()) -> Result {
-            (*self)()
-        }
-    }
-
-    impl<Result,A0> Fn<(A0,),Result> for extern "Rust" fn(A0) -> Result {
-        #[allow(non_snake_case)]
-        extern "rust-call" fn call(&self, args: (A0,)) -> Result {
-            let (a0,) = args;
-            (*self)(a0)
-        }
-    }
-
-    macro_rules! def_fn(
-        ($($args:ident)*) => (
-            impl<Result$(,$args)*>
-            Fn<($($args,)*),Result>
-            for extern "Rust" fn($($args: $args,)*) -> Result {
-                #[allow(non_snake_case)]
-                extern "rust-call" fn call(&self, args: ($($args,)*)) -> Result {
-                    let ($($args,)*) = args;
-                    (*self)($($args,)*)
-                }
-            }
-        )
-    )
-
-    def_fn!(A0 A1)
-    def_fn!(A0 A1 A2)
-    def_fn!(A0 A1 A2 A3)
-    def_fn!(A0 A1 A2 A3 A4)
-    def_fn!(A0 A1 A2 A3 A4 A5)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14)
-    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15)
-}
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index ef895a1d7fb..8ba41c3575f 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -149,7 +149,8 @@ use cmp::{Eq, Ord};
 use default::Default;
 use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
 use mem;
-use result::{Result, Ok, Err};
+use result::Result;
+use result::Result::{Ok, Err};
 use slice;
 use slice::AsSlice;
 use clone::Clone;
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 416bc4588b4..3f6ac49786d 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -90,9 +90,12 @@
 use mem;
 use clone::Clone;
 use intrinsics;
-use option::{Some, None, Option};
+use option::Option;
+use option::Option::{Some, None};
 
-use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
+use cmp::{PartialEq, Eq, PartialOrd, Equiv};
+use cmp::Ordering;
+use cmp::Ordering::{Less, Equal, Greater};
 
 pub use intrinsics::copy_memory;
 pub use intrinsics::copy_nonoverlapping_memory;
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 7c88106c9ec..0cf8e6affd7 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -236,7 +236,8 @@ use std::fmt::Show;
 use slice;
 use slice::AsSlice;
 use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
-use option::{None, Option, Some};
+use option::Option;
+use option::Option::{None, Some};
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 ///
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 85bd6adf8b8..b8df36c91bc 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -36,13 +36,15 @@
 
 use mem::transmute;
 use clone::Clone;
-use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Less, Equal, Greater, Equiv};
+use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord, Equiv};
+use cmp::Ordering::{Less, Equal, Greater};
 use cmp;
 use default::Default;
 use iter::*;
 use num::Int;
 use ops;
-use option::{None, Option, Some};
+use option::Option;
+use option::Option::{None, Some};
 use ptr;
 use ptr::RawPtr;
 use mem;
@@ -1702,7 +1704,8 @@ pub mod raw {
     use mem::transmute;
     use ptr::RawPtr;
     use raw::Slice;
-    use option::{None, Option, Some};
+    use option::Option;
+    use option::Option::{None, Some};
 
     /// Form a slice from a pointer and length (as a number of units,
     /// not bytes).
@@ -1781,12 +1784,13 @@ pub mod bytes {
 
     /// Copies data from `src` to `dst`
     ///
-    /// `src` and `dst` must not overlap. Panics if the length of `dst`
-    /// is less than the length of `src`.
+    /// Panics if the length of `dst` is less than the length of `src`.
     #[inline]
     pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
         let len_src = src.len();
         assert!(dst.len() >= len_src);
+        // `dst` is unaliasable, so we know statically it doesn't overlap
+        // with `src`.
         unsafe {
             ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(),
                                             src.as_ptr(),
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 4be628f0ac3..1d59567cbe4 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -29,7 +29,8 @@ use iter::range;
 use kinds::Sized;
 use mem;
 use num::Int;
-use option::{Option, None, Some};
+use option::Option;
+use option::Option::{None, Some};
 use ptr::RawPtr;
 use raw::{Repr, Slice};
 use slice::{mod, SlicePrelude};
@@ -1209,9 +1210,11 @@ Section: Trait implementations
 
 #[allow(missing_docs)]
 pub mod traits {
-    use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq};
+    use cmp::{Ordering, Ord, PartialEq, PartialOrd, Equiv, Eq};
+    use cmp::Ordering::{Less, Equal, Greater};
     use iter::IteratorExt;
-    use option::{Option, Some};
+    use option::Option;
+    use option::Option::Some;
     use ops;
     use str::{Str, StrPrelude, eq_slice};
 
diff --git a/src/libcore/tuple/mod.rs b/src/libcore/tuple/mod.rs
index 56ea7a4e7a1..5ad01ae6744 100644
--- a/src/libcore/tuple/mod.rs
+++ b/src/libcore/tuple/mod.rs
@@ -69,7 +69,8 @@ pub use unit;
 use clone::Clone;
 use cmp::*;
 use default::Default;
-use option::{Option, Some};
+use option::Option;
+use option::Option::Some;
 
 // macro for implementing n-ary tuple functions and operations
 macro_rules! tuple_impls {
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
index 0cd1ded21d6..6ee3633d36c 100644
--- a/src/libcoretest/num/mod.rs
+++ b/src/libcoretest/num/mod.rs
@@ -48,7 +48,8 @@ pub fn test_num<T>(ten: T, two: T) where
 
 #[cfg(test)]
 mod test {
-    use core::option::{Option, Some, None};
+    use core::option::Option;
+    use core::option::Option::{Some, None};
     use core::num::Float;
     use core::num::from_str_radix;
 
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 6b8fafbed5d..03b65b3f71c 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -18,6 +18,11 @@
 #![experimental]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+       html_root_url = "http://doc.rust-lang.org/nightly/",
+       html_playground_url = "http://play.rust-lang.org/")]
+
 #![feature(macro_rules, globs, import_shadowing)]
 pub use self::Piece::*;
 pub use self::Position::*;
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index 1204ac18f99..e146e3c76eb 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -99,7 +99,7 @@ use self::Fail::*;
 use self::Optval::*;
 
 use std::fmt;
-use std::result::{Err, Ok};
+use std::result::Result::{Err, Ok};
 use std::result;
 use std::string::String;
 
@@ -951,7 +951,7 @@ mod tests {
     use super::*;
     use super::Fail::*;
 
-    use std::result::{Err, Ok};
+    use std::result::Result::{Err, Ok};
     use std::result;
 
     // Tests for reqopt
@@ -1392,8 +1392,8 @@ mod tests {
         let args_single = vec!("-e".to_string(), "foo".to_string());
         let matches_single = &match getopts(args_single.as_slice(),
                                             opts.as_slice()) {
-          result::Ok(m) => m,
-          result::Err(_) => panic!()
+          result::Result::Ok(m) => m,
+          result::Result::Err(_) => panic!()
         };
         assert!(matches_single.opts_present(&["e".to_string()]));
         assert!(matches_single.opts_present(&["encrypt".to_string(), "e".to_string()]));
@@ -1412,8 +1412,8 @@ mod tests {
                              "foo".to_string());
         let matches_both = &match getopts(args_both.as_slice(),
                                           opts.as_slice()) {
-          result::Ok(m) => m,
-          result::Err(_) => panic!()
+          result::Result::Ok(m) => m,
+          result::Result::Err(_) => panic!()
         };
         assert!(matches_both.opts_present(&["e".to_string()]));
         assert!(matches_both.opts_present(&["encrypt".to_string()]));
@@ -1437,8 +1437,8 @@ mod tests {
         let opts = vec!(optmulti("L", "", "library directory", "LIB"),
                      optmulti("M", "", "something", "MMMM"));
         let matches = &match getopts(args.as_slice(), opts.as_slice()) {
-          result::Ok(m) => m,
-          result::Err(_) => panic!()
+          result::Result::Ok(m) => m,
+          result::Result::Err(_) => panic!()
         };
         assert!(matches.opts_present(&["L".to_string()]));
         assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "foo".to_string());
@@ -1453,8 +1453,8 @@ mod tests {
         let opts = vec!(optmulti("L", "", "library directory", "LIB"),
                      optflagmulti("v", "verbose", "Verbose"));
         let matches = &match getopts(args.as_slice(), opts.as_slice()) {
-          result::Ok(m) => m,
-          result::Err(e) => panic!( "{}", e )
+          result::Result::Ok(m) => m,
+          result::Result::Err(e) => panic!( "{}", e )
         };
         assert!(matches.opts_present(&["L".to_string()]));
         assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "verbose".to_string());
diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs
index 6f3fbe12510..f65c4f4e3ed 100644
--- a/src/librbml/lib.rs
+++ b/src/librbml/lib.rs
@@ -120,7 +120,8 @@ pub mod reader {
     use std::io::extensions::u64_from_be_bytes;
     use std::mem::transmute;
     use std::num::Int;
-    use std::option::{None, Option, Some};
+    use std::option::Option;
+    use std::option::Option::{None, Some};
 
     use serialize;
 
@@ -1060,7 +1061,8 @@ mod tests {
 
     use serialize::{Encodable, Decodable};
 
-    use std::option::{None, Option, Some};
+    use std::option::Option;
+    use std::option::Option::{None, Some};
 
     #[test]
     fn test_vuint_at() {
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index a83f8afd396..a964609e4e6 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -59,6 +59,7 @@ pub mod back {
 }
 
 pub mod middle {
+    pub mod astconv_util;
     pub mod astencode;
     pub mod borrowck;
     pub mod cfg;
@@ -79,6 +80,7 @@ pub mod middle {
     pub mod fast_reject;
     pub mod graph;
     pub mod intrinsicck;
+    pub mod infer;
     pub mod lang_items;
     pub mod liveness;
     pub mod mem_categorization;
@@ -93,7 +95,6 @@ pub mod middle {
     pub mod traits;
     pub mod ty;
     pub mod ty_fold;
-    pub mod typeck;
     pub mod weak_lang_items;
 }
 
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 9a214d531d1..b0ac98c94e7 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -29,8 +29,6 @@ use self::MethodContext::*;
 use metadata::csearch;
 use middle::def::*;
 use middle::ty::{mod, Ty};
-use middle::typeck::astconv::ast_ty_to_ty;
-use middle::typeck::{mod, infer};
 use middle::{def, pat_util, stability};
 use middle::const_eval::{eval_const_expr_partial, const_int, const_uint};
 use util::ppaux::{ty_to_string};
@@ -84,7 +82,7 @@ impl LintPass for UnusedCasts {
 
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
         if let ast::ExprCast(ref expr, ref ty) = e.node {
-            let t_t = ast_ty_to_ty(cx, &infer::new_infer_ctxt(cx.tcx), &**ty);
+            let t_t = ty::expr_ty(cx.tcx, e);
             if ty::expr_ty(cx.tcx, &**expr) == t_t {
                 cx.span_lint(UNUSED_TYPECASTS, ty.span, "unnecessary type cast");
             }
@@ -1430,6 +1428,7 @@ impl LintPass for MissingDoc {
             ast::ItemEnum(..) => "an enum",
             ast::ItemStruct(..) => "a struct",
             ast::ItemTrait(..) => "a trait",
+            ast::ItemTy(..) => "a type alias",
             _ => return
         };
         self.check_missing_docs_attrs(cx, Some(it.id), it.attrs.as_slice(),
@@ -1589,22 +1588,22 @@ impl LintPass for Stability {
             }
             ast::ExprMethodCall(i, _, _) => {
                 span = i.span;
-                let method_call = typeck::MethodCall::expr(e.id);
+                let method_call = ty::MethodCall::expr(e.id);
                 match cx.tcx.method_map.borrow().get(&method_call) {
                     Some(method) => {
                         match method.origin {
-                            typeck::MethodStatic(def_id) => {
+                            ty::MethodStatic(def_id) => {
                                 def_id
                             }
-                            typeck::MethodStaticUnboxedClosure(def_id) => {
+                            ty::MethodStaticUnboxedClosure(def_id) => {
                                 def_id
                             }
-                            typeck::MethodTypeParam(typeck::MethodParam {
+                            ty::MethodTypeParam(ty::MethodParam {
                                 ref trait_ref,
                                 method_num: index,
                                 ..
                             }) |
-                            typeck::MethodTraitObject(typeck::MethodObject {
+                            ty::MethodTraitObject(ty::MethodObject {
                                 ref trait_ref,
                                 method_num: index,
                                 ..
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index c7bed838eb9..442d3aab92d 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -26,17 +26,13 @@
 use self::TargetLint::*;
 
 use middle::privacy::ExportedItems;
-use middle::subst;
 use middle::ty::{mod, Ty};
-use middle::typeck::astconv::AstConv;
-use middle::typeck::infer;
 use session::{early_error, Session};
 use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass, LintPassObject};
 use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid};
 use lint::builtin;
 use util::nodemap::FnvHashMap;
 
-use std::rc::Rc;
 use std::cell::RefCell;
 use std::tuple::Tuple2;
 use std::mem;
@@ -541,42 +537,6 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> AstConv<'tcx> for Context<'a, 'tcx>{
-    fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }
-
-    fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype<'tcx> {
-        ty::lookup_item_type(self.tcx, id)
-    }
-
-    fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef<'tcx>> {
-        ty::lookup_trait_def(self.tcx, id)
-    }
-
-    fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
-        infer::new_infer_ctxt(self.tcx).next_ty_var()
-    }
-
-    fn associated_types_of_trait_are_valid(&self, _: Ty<'tcx>, _: ast::DefId)
-                                           -> bool {
-        // FIXME(pcwalton): This is wrong.
-        true
-    }
-
-    fn associated_type_binding(&self,
-                               _: Span,
-                               _: Option<Ty<'tcx>>,
-                               trait_id: ast::DefId,
-                               associated_type_id: ast::DefId)
-                               -> Ty<'tcx> {
-        // FIXME(pcwalton): This is wrong.
-        let trait_def = self.get_trait_def(trait_id);
-        let index = ty::associated_type_parameter_index(self.tcx,
-                                                        &*trait_def,
-                                                        associated_type_id);
-        ty::mk_param(self.tcx, subst::TypeSpace, index, associated_type_id)
-    }
-}
-
 impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
     fn visit_item(&mut self, it: &ast::Item) {
         self.with_lint_attrs(it.attrs.as_slice(), |cx| {
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 20e3f27f2ae..ebf5cca6a31 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -21,7 +21,6 @@ use middle::def;
 use middle::lang_items;
 use middle::resolve;
 use middle::ty;
-use middle::typeck;
 use middle::subst::VecPerParamSpace;
 
 use rbml;
@@ -268,7 +267,7 @@ pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
 // Given a def_id for an impl, return information about its vtables
 pub fn get_impl_vtables<'tcx>(tcx: &ty::ctxt<'tcx>,
                               def: ast::DefId)
-                              -> typeck::vtable_res<'tcx> {
+                              -> ty::vtable_res<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_impl_vtables(&*cdata, def.node, tcx)
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index ec812cea372..f352a28df69 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -30,7 +30,6 @@ use middle::resolve::{TraitItemKind, TypeTraitItemKind};
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty::{mod, Ty};
-use middle::typeck;
 use middle::astencode::vtable_decoder_helpers;
 
 use std::hash::Hash;
@@ -422,7 +421,7 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
 pub fn get_impl_vtables<'tcx>(cdata: Cmd,
                               id: ast::NodeId,
                               tcx: &ty::ctxt<'tcx>)
-                              -> typeck::vtable_res<'tcx>
+                              -> ty::vtable_res<'tcx>
 {
     let item_doc = lookup_item(id, cdata.data());
     let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables);
diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs
new file mode 100644
index 00000000000..6b90bcd60e7
--- /dev/null
+++ b/src/librustc/middle/astconv_util.rs
@@ -0,0 +1,89 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+ * This module contains a simple utility routine
+ * used by both `typeck` and `const_eval`.
+ * Almost certainly this could (and should) be refactored out of existence.
+ */
+
+use middle::def;
+use middle::ty::{mod, Ty};
+use syntax::ast;
+use util::ppaux::Repr;
+
+pub const NO_REGIONS: uint = 1;
+pub const NO_TPS: uint = 2;
+
+pub fn check_path_args(tcx: &ty::ctxt,
+                       path: &ast::Path,
+                       flags: uint) {
+    if (flags & NO_TPS) != 0u {
+        if path.segments.iter().any(|s| s.parameters.has_types()) {
+            span_err!(tcx.sess, path.span, E0109,
+                "type parameters are not allowed on this type");
+        }
+    }
+
+    if (flags & NO_REGIONS) != 0u {
+        if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
+            span_err!(tcx.sess, path.span, E0110,
+                "region parameters are not allowed on this type");
+        }
+    }
+}
+
+pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
+                               -> Option<Ty<'tcx>> {
+    match ast_ty.node {
+        ast::TyPath(ref path, id) => {
+            let a_def = match tcx.def_map.borrow().get(&id) {
+                None => {
+                    tcx.sess.span_bug(ast_ty.span,
+                                      format!("unbound path {}",
+                                              path.repr(tcx)).as_slice())
+                }
+                Some(&d) => d
+            };
+            match a_def {
+                def::DefPrimTy(nty) => {
+                    match nty {
+                        ast::TyBool => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_bool())
+                        }
+                        ast::TyChar => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_char())
+                        }
+                        ast::TyInt(it) => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_mach_int(it))
+                        }
+                        ast::TyUint(uit) => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_mach_uint(uit))
+                        }
+                        ast::TyFloat(ft) => {
+                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
+                            Some(ty::mk_mach_float(ft))
+                        }
+                        ast::TyStr => {
+                            Some(ty::mk_str(tcx))
+                        }
+                    }
+                }
+                _ => None
+            }
+        }
+        _ => None
+    }
+}
+
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 523e997a8de..113d127503f 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -26,8 +26,7 @@ use metadata::tyencode;
 use middle::mem_categorization::Typer;
 use middle::subst;
 use middle::subst::VecPerParamSpace;
-use middle::typeck::{mod, MethodCall, MethodCallee, MethodOrigin};
-use middle::ty::{mod, Ty};
+use middle::ty::{mod, Ty, MethodCall, MethodCallee, MethodOrigin};
 use util::ppaux::ty_to_string;
 
 use syntax::{ast, ast_map, ast_util, codemap, fold};
@@ -576,12 +575,12 @@ impl tr for ty::UpvarBorrow {
 
 trait read_method_callee_helper<'tcx> {
     fn read_method_callee<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-        -> (typeck::ExprAdjustment, MethodCallee<'tcx>);
+        -> (ty::ExprAdjustment, MethodCallee<'tcx>);
 }
 
 fn encode_method_callee<'a, 'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
                                   rbml_w: &mut Encoder,
-                                  adjustment: typeck::ExprAdjustment,
+                                  adjustment: ty::ExprAdjustment,
                                   method: &MethodCallee<'tcx>) {
     use serialize::Encoder;
 
@@ -603,7 +602,7 @@ fn encode_method_callee<'a, 'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
 
 impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
     fn read_method_callee<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-        -> (typeck::ExprAdjustment, MethodCallee<'tcx>) {
+        -> (ty::ExprAdjustment, MethodCallee<'tcx>) {
 
         self.read_struct("MethodCallee", 4, |this| {
             let adjustment = this.read_struct_field("adjustment", 0, |this| {
@@ -627,22 +626,22 @@ impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
 impl<'tcx> tr for MethodOrigin<'tcx> {
     fn tr(&self, dcx: &DecodeContext) -> MethodOrigin<'tcx> {
         match *self {
-            typeck::MethodStatic(did) => typeck::MethodStatic(did.tr(dcx)),
-            typeck::MethodStaticUnboxedClosure(did) => {
-                typeck::MethodStaticUnboxedClosure(did.tr(dcx))
+            ty::MethodStatic(did) => ty::MethodStatic(did.tr(dcx)),
+            ty::MethodStaticUnboxedClosure(did) => {
+                ty::MethodStaticUnboxedClosure(did.tr(dcx))
             }
-            typeck::MethodTypeParam(ref mp) => {
-                typeck::MethodTypeParam(
-                    typeck::MethodParam {
+            ty::MethodTypeParam(ref mp) => {
+                ty::MethodTypeParam(
+                    ty::MethodParam {
                         // def-id is already translated when we read it out
                         trait_ref: mp.trait_ref.clone(),
                         method_num: mp.method_num,
                     }
                 )
             }
-            typeck::MethodTraitObject(ref mo) => {
-                typeck::MethodTraitObject(
-                    typeck::MethodObject {
+            ty::MethodTraitObject(ref mo) => {
+                ty::MethodTraitObject(
+                    ty::MethodObject {
                         trait_ref: mo.trait_ref.clone(),
                         .. *mo
                     }
@@ -687,16 +686,16 @@ pub trait vtable_decoder_helpers<'tcx> {
     fn read_vtable_res_with_key(&mut self,
                                 tcx: &ty::ctxt<'tcx>,
                                 cdata: &cstore::crate_metadata)
-                                -> (typeck::ExprAdjustment, typeck::vtable_res<'tcx>);
+                                -> (ty::ExprAdjustment, ty::vtable_res<'tcx>);
     fn read_vtable_res(&mut self,
                        tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
-                      -> typeck::vtable_res<'tcx>;
+                      -> ty::vtable_res<'tcx>;
     fn read_vtable_param_res(&mut self,
                        tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
-                      -> typeck::vtable_param_res<'tcx>;
+                      -> ty::vtable_param_res<'tcx>;
     fn read_vtable_origin(&mut self,
                           tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
-                          -> typeck::vtable_origin<'tcx>;
+                          -> ty::vtable_origin<'tcx>;
 }
 
 impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
@@ -714,7 +713,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
     fn read_vtable_res_with_key(&mut self,
                                 tcx: &ty::ctxt<'tcx>,
                                 cdata: &cstore::crate_metadata)
-                                -> (typeck::ExprAdjustment, typeck::vtable_res<'tcx>) {
+                                -> (ty::ExprAdjustment, ty::vtable_res<'tcx>) {
         self.read_struct("VtableWithKey", 2, |this| {
             let adjustment = this.read_struct_field("adjustment", 0, |this| {
                 Decodable::decode(this)
@@ -728,7 +727,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
     fn read_vtable_res(&mut self,
                        tcx: &ty::ctxt<'tcx>,
                        cdata: &cstore::crate_metadata)
-                       -> typeck::vtable_res<'tcx>
+                       -> ty::vtable_res<'tcx>
     {
         self.read_vec_per_param_space(
             |this| this.read_vtable_param_res(tcx, cdata))
@@ -736,14 +735,14 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
 
     fn read_vtable_param_res(&mut self,
                              tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
-                      -> typeck::vtable_param_res<'tcx> {
+                      -> ty::vtable_param_res<'tcx> {
         self.read_to_vec(|this| Ok(this.read_vtable_origin(tcx, cdata)))
              .unwrap().into_iter().collect()
     }
 
     fn read_vtable_origin(&mut self,
                           tcx: &ty::ctxt<'tcx>, cdata: &cstore::crate_metadata)
-        -> typeck::vtable_origin<'tcx> {
+        -> ty::vtable_origin<'tcx> {
         self.read_enum("vtable_origin", |this| {
             this.read_enum_variant(&["vtable_static",
                                      "vtable_param",
@@ -752,7 +751,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
                                    |this, i| {
                 Ok(match i {
                   0 => {
-                    typeck::vtable_static(
+                    ty::vtable_static(
                         this.read_enum_variant_arg(0u, |this| {
                             Ok(this.read_def_id_nodcx(cdata))
                         }).unwrap(),
@@ -765,7 +764,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
                     )
                   }
                   1 => {
-                    typeck::vtable_param(
+                    ty::vtable_param(
                         this.read_enum_variant_arg(0u, |this| {
                             Decodable::decode(this)
                         }).unwrap(),
@@ -775,14 +774,14 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
                     )
                   }
                   2 => {
-                    typeck::vtable_unboxed_closure(
+                    ty::vtable_unboxed_closure(
                         this.read_enum_variant_arg(0u, |this| {
                             Ok(this.read_def_id_nodcx(cdata))
                         }).unwrap()
                     )
                   }
                   3 => {
-                    typeck::vtable_error
+                    ty::vtable_error
                   }
                   _ => panic!("bad enum variant")
                 })
@@ -826,7 +825,7 @@ trait rbml_writer_helpers<'tcx> {
                              closure_type: &ty::ClosureTy<'tcx>);
     fn emit_method_origin<'a>(&mut self,
                               ecx: &e::EncodeContext<'a, 'tcx>,
-                              method_origin: &typeck::MethodOrigin<'tcx>);
+                              method_origin: &ty::MethodOrigin<'tcx>);
     fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
     fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
     fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
@@ -860,25 +859,25 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
 
     fn emit_method_origin<'a>(&mut self,
                               ecx: &e::EncodeContext<'a, 'tcx>,
-                              method_origin: &typeck::MethodOrigin<'tcx>)
+                              method_origin: &ty::MethodOrigin<'tcx>)
     {
         use serialize::Encoder;
 
         self.emit_enum("MethodOrigin", |this| {
             match *method_origin {
-                typeck::MethodStatic(def_id) => {
+                ty::MethodStatic(def_id) => {
                     this.emit_enum_variant("MethodStatic", 0, 1, |this| {
                         Ok(this.emit_def_id(def_id))
                     })
                 }
 
-                typeck::MethodStaticUnboxedClosure(def_id) => {
+                ty::MethodStaticUnboxedClosure(def_id) => {
                     this.emit_enum_variant("MethodStaticUnboxedClosure", 1, 1, |this| {
                         Ok(this.emit_def_id(def_id))
                     })
                 }
 
-                typeck::MethodTypeParam(ref p) => {
+                ty::MethodTypeParam(ref p) => {
                     this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
                         this.emit_struct("MethodParam", 2, |this| {
                             try!(this.emit_struct_field("trait_ref", 0, |this| {
@@ -892,7 +891,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
                     })
                 }
 
-                typeck::MethodTraitObject(ref o) => {
+                ty::MethodTraitObject(ref o) => {
                     this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
                         this.emit_struct("MethodObject", 2, |this| {
                             try!(this.emit_struct_field("trait_ref", 0, |this| {
@@ -1330,7 +1329,7 @@ impl<'a> doc_decoder_helpers for rbml::Doc<'a> {
 
 trait rbml_decoder_decoder_helpers<'tcx> {
     fn read_method_origin<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-                                  -> typeck::MethodOrigin<'tcx>;
+                                  -> ty::MethodOrigin<'tcx>;
     fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>;
     fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
     fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -1409,7 +1408,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
     }
 
     fn read_method_origin<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-                                  -> typeck::MethodOrigin<'tcx>
+                                  -> ty::MethodOrigin<'tcx>
     {
         self.read_enum("MethodOrigin", |this| {
             let variants = &["MethodStatic", "MethodStaticUnboxedClosure",
@@ -1418,18 +1417,18 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                 Ok(match i {
                     0 => {
                         let def_id = this.read_def_id(dcx);
-                        typeck::MethodStatic(def_id)
+                        ty::MethodStatic(def_id)
                     }
 
                     1 => {
                         let def_id = this.read_def_id(dcx);
-                        typeck::MethodStaticUnboxedClosure(def_id)
+                        ty::MethodStaticUnboxedClosure(def_id)
                     }
 
                     2 => {
                         this.read_struct("MethodTypeParam", 2, |this| {
-                            Ok(typeck::MethodTypeParam(
-                                typeck::MethodParam {
+                            Ok(ty::MethodTypeParam(
+                                ty::MethodParam {
                                     trait_ref: {
                                         this.read_struct_field("trait_ref", 0, |this| {
                                             Ok(this.read_trait_ref(dcx))
@@ -1446,8 +1445,8 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
 
                     3 => {
                         this.read_struct("MethodTraitObject", 2, |this| {
-                            Ok(typeck::MethodTraitObject(
-                                typeck::MethodObject {
+                            Ok(ty::MethodTraitObject(
+                                ty::MethodObject {
                                     trait_ref: {
                                         this.read_struct_field("trait_ref", 0, |this| {
                                             Ok(this.read_trait_ref(dcx))
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index b42fb8ccc41..90919609e2e 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -12,7 +12,6 @@ use middle::cfg::*;
 use middle::def;
 use middle::graph;
 use middle::region::CodeExtent;
-use middle::typeck;
 use middle::ty;
 use syntax::ast;
 use syntax::ast_util;
@@ -510,7 +509,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
             pred: CFGIndex,
             func_or_rcvr: &ast::Expr,
             args: I) -> CFGIndex {
-        let method_call = typeck::MethodCall::expr(call_expr.id);
+        let method_call = ty::MethodCall::expr(call_expr.id);
         let return_ty = ty::ty_fn_ret(match self.tcx.method_map.borrow().get(&method_call) {
             Some(method) => method.ty,
             None => ty::expr_ty(self.tcx, func_or_rcvr)
@@ -635,7 +634,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     }
 
     fn is_method_call(&self, expr: &ast::Expr) -> bool {
-        let method_call = typeck::MethodCall::expr(expr.id);
+        let method_call = ty::MethodCall::expr(expr.id);
         self.tcx.method_map.borrow().contains_key(&method_call)
     }
 }
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 8cb63fcd827..de140fd5c30 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -11,7 +11,6 @@
 
 use middle::def::*;
 use middle::ty;
-use middle::typeck;
 use util::ppaux;
 
 use syntax::ast;
@@ -111,7 +110,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
         }
         ast::ExprLit(ref lit) if ast_util::lit_is_str(&**lit) => {}
         ast::ExprBinary(..) | ast::ExprUnary(..) => {
-            let method_call = typeck::MethodCall::expr(e.id);
+            let method_call = ty::MethodCall::expr(e.id);
             if v.tcx.method_map.borrow().contains_key(&method_call) {
                 span_err!(v.tcx.sess, e.span, E0011,
                           "user-defined operators are not allowed in constant \
diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs
index d3c7ccf65dd..2fc85afd393 100644
--- a/src/librustc/middle/check_static.rs
+++ b/src/librustc/middle/check_static.rs
@@ -27,7 +27,7 @@ use self::Mode::*;
 
 use middle::ty;
 use middle::def;
-use middle::typeck;
+use middle::infer;
 use middle::traits;
 use middle::mem_categorization as mc;
 use middle::expr_use_visitor as euv;
@@ -113,7 +113,7 @@ impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
 
     fn check_static_type(&self, e: &ast::Expr) {
         let ty = ty::node_id_to_type(self.tcx, e.id);
-        let infcx = typeck::infer::new_infer_ctxt(self.tcx);
+        let infcx = infer::new_infer_ctxt(self.tcx);
         let mut fulfill_cx = traits::FulfillmentContext::new();
         let cause = traits::ObligationCause::misc(DUMMY_SP);
         let obligation = traits::obligation_for_builtin_bound(self.tcx, cause, ty,
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index d5a292b9f09..43726f55bb9 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -17,8 +17,8 @@ pub use self::constness::*;
 use metadata::csearch;
 use middle::{astencode, def};
 use middle::pat_util::def_to_path;
-use middle::ty::{mod, Ty};
-use middle::typeck::{astconv, check};
+use middle::ty::{mod};
+use middle::astconv_util::{ast_ty_to_prim_ty};
 use util::nodemap::DefIdMap;
 
 use syntax::ast::{mod, Expr};
@@ -277,14 +277,6 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for ConstEvalVisitor<'a, 'tcx> {
-    fn visit_ty(&mut self, t: &ast::Ty) {
-        if let ast::TyFixedLengthVec(_, ref expr) = t.node {
-            check::check_const_in_type(self.tcx, &**expr, ty::mk_uint());
-        }
-
-        visit::walk_ty(self, t);
-    }
-
     fn visit_expr_post(&mut self, e: &Expr) {
         self.classify(e);
     }
@@ -504,7 +496,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
         // populated in the ctxt, which was causing things to blow up
         // (#5900). Fall back to doing a limited lookup to get past it.
         let ety = ty::expr_ty_opt(tcx, e)
-                .or_else(|| astconv::ast_ty_to_prim_ty(tcx, &**target_ty))
+                .or_else(|| ast_ty_to_prim_ty(tcx, &**target_ty))
                 .unwrap_or_else(|| {
                     tcx.sess.span_fatal(target_ty.span,
                                         "target type not found for const cast")
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index cf2e9a65859..03fe8782421 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -12,7 +12,7 @@
 // closely. The idea is that all reachable symbols are live, codes called
 // from live codes are live, and everything else is dead.
 
-use middle::{def, pat_util, privacy, ty, typeck};
+use middle::{def, pat_util, privacy, ty};
 use lint;
 use util::nodemap::NodeSet;
 
@@ -90,23 +90,23 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn lookup_and_handle_method(&mut self, id: ast::NodeId,
                                 span: codemap::Span) {
-        let method_call = typeck::MethodCall::expr(id);
+        let method_call = ty::MethodCall::expr(id);
         match self.tcx.method_map.borrow().get(&method_call) {
             Some(method) => {
                 match method.origin {
-                    typeck::MethodStatic(def_id) => {
+                    ty::MethodStatic(def_id) => {
                         match ty::provided_source(self.tcx, def_id) {
                             Some(p_did) => self.check_def_id(p_did),
                             None => self.check_def_id(def_id)
                         }
                     }
-                    typeck::MethodStaticUnboxedClosure(_) => {}
-                    typeck::MethodTypeParam(typeck::MethodParam {
+                    ty::MethodStaticUnboxedClosure(_) => {}
+                    ty::MethodTypeParam(ty::MethodParam {
                         ref trait_ref,
                         method_num: index,
                         ..
                     }) |
-                    typeck::MethodTraitObject(typeck::MethodObject {
+                    ty::MethodTraitObject(ty::MethodObject {
                         ref trait_ref,
                         method_num: index,
                         ..
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index e67df0332dc..dbec69f4205 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -14,7 +14,7 @@ use self::UnsafeContext::*;
 
 use middle::def;
 use middle::ty::{mod, Ty};
-use middle::typeck::MethodCall;
+use middle::ty::MethodCall;
 use util::ppaux;
 
 use syntax::ast;
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index cbf36aeff51..7d2bb7458ac 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -24,10 +24,9 @@ use middle::{def, region, pat_util};
 use middle::mem_categorization as mc;
 use middle::mem_categorization::Typer;
 use middle::ty::{mod, Ty};
-use middle::typeck::{MethodCall, MethodObject, MethodTraitObject};
-use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam};
-use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure};
-use middle::typeck;
+use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
+use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
+use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
 use util::ppaux::Repr;
 
 use syntax::ast;
@@ -825,7 +824,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
         debug!("walk_autoderefs expr={} autoderefs={}", expr.repr(self.tcx()), autoderefs);
 
         for i in range(0, autoderefs) {
-            let deref_id = typeck::MethodCall::autoderef(expr.id, i);
+            let deref_id = ty::MethodCall::autoderef(expr.id, i);
             match self.typer.node_method_ty(deref_id) {
                 None => {}
                 Some(method_ty) => {
diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs
index 51f8668692e..f04c519badc 100644
--- a/src/librustc/middle/typeck/infer/coercion.rs
+++ b/src/librustc/middle/infer/coercion.rs
@@ -60,14 +60,15 @@
 //! sort of a minor point so I've opted to leave it for later---after all
 //! we may want to adjust precisely when coercions occur.
 
+use super::{CoerceResult, resolve_type, Coercion};
+use super::combine::{CombineFields, Combine};
+use super::sub::Sub;
+use super::resolve::try_resolve_tvar_shallow;
+
 use middle::subst;
 use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe};
 use middle::ty::{mt};
 use middle::ty::{mod, Ty};
-use middle::typeck::infer::{CoerceResult, resolve_type, Coercion};
-use middle::typeck::infer::combine::{CombineFields, Combine};
-use middle::typeck::infer::sub::Sub;
-use middle::typeck::infer::resolve::try_resolve_tvar_shallow;
 use util::ppaux;
 use util::ppaux::Repr;
 
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index ba6ae00b667..ab9c5b86aeb 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -32,6 +32,14 @@
 // is also useful to track which value is the "expected" value in
 // terms of error reporting.
 
+use super::equate::Equate;
+use super::glb::Glb;
+use super::lub::Lub;
+use super::sub::Sub;
+use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
+use super::{InferCtxt, cres};
+use super::{MiscVariable, TypeTrace};
+use super::type_variable::{RelationDir, EqTo, SubtypeOf, SupertypeOf};
 
 use middle::subst;
 use middle::subst::{ErasedRegions, NonerasedRegions, Substs};
@@ -40,15 +48,6 @@ use middle::ty::{IntType, UintType};
 use middle::ty::{BuiltinBounds};
 use middle::ty::{mod, Ty};
 use middle::ty_fold;
-use middle::typeck::infer::equate::Equate;
-use middle::typeck::infer::glb::Glb;
-use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::sub::Sub;
-use middle::typeck::infer::unify::InferCtxtMethodsForSimplyUnifiableTypes;
-use middle::typeck::infer::{InferCtxt, cres};
-use middle::typeck::infer::{MiscVariable, TypeTrace};
-use middle::typeck::infer::type_variable::{RelationDir, EqTo,
-                                           SubtypeOf, SupertypeOf};
 use middle::ty_fold::{TypeFoldable};
 use util::ppaux::Repr;
 
diff --git a/src/librustc/middle/typeck/infer/doc.rs b/src/librustc/middle/infer/doc.rs
index 0e3cc5f68c8..0e3cc5f68c8 100644
--- a/src/librustc/middle/typeck/infer/doc.rs
+++ b/src/librustc/middle/infer/doc.rs
diff --git a/src/librustc/middle/typeck/infer/equate.rs b/src/librustc/middle/infer/equate.rs
index 356081c199a..a79a50b1781 100644
--- a/src/librustc/middle/typeck/infer/equate.rs
+++ b/src/librustc/middle/infer/equate.rs
@@ -11,14 +11,14 @@
 use middle::ty::{BuiltinBounds};
 use middle::ty::{mod, Ty};
 use middle::ty::TyVar;
-use middle::typeck::infer::combine::*;
-use middle::typeck::infer::{cres};
-use middle::typeck::infer::glb::Glb;
-use middle::typeck::infer::InferCtxt;
-use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::sub::Sub;
-use middle::typeck::infer::{TypeTrace, Subtype};
-use middle::typeck::infer::type_variable::{EqTo};
+use middle::infer::combine::*;
+use middle::infer::{cres};
+use middle::infer::glb::Glb;
+use middle::infer::InferCtxt;
+use middle::infer::lub::Lub;
+use middle::infer::sub::Sub;
+use middle::infer::{TypeTrace, Subtype};
+use middle::infer::type_variable::{EqTo};
 use util::ppaux::{Repr};
 
 use syntax::ast::{Onceness, FnStyle};
diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 0607ccdc595..657ee088758 100644
--- a/src/librustc/middle/typeck/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -57,24 +57,25 @@
 
 use self::FreshOrKept::*;
 
+use super::InferCtxt;
+use super::TypeTrace;
+use super::SubregionOrigin;
+use super::RegionVariableOrigin;
+use super::ValuePairs;
+use super::region_inference::RegionResolutionError;
+use super::region_inference::ConcreteFailure;
+use super::region_inference::SubSupConflict;
+use super::region_inference::SupSupConflict;
+use super::region_inference::ParamBoundFailure;
+use super::region_inference::ProcessedErrors;
+use super::region_inference::SameRegions;
+
 use std::collections::HashSet;
 use middle::def;
+use middle::infer;
 use middle::subst;
 use middle::ty::{mod, Ty};
 use middle::ty::{Region, ReFree};
-use middle::typeck::infer;
-use middle::typeck::infer::InferCtxt;
-use middle::typeck::infer::TypeTrace;
-use middle::typeck::infer::SubregionOrigin;
-use middle::typeck::infer::RegionVariableOrigin;
-use middle::typeck::infer::ValuePairs;
-use middle::typeck::infer::region_inference::RegionResolutionError;
-use middle::typeck::infer::region_inference::ConcreteFailure;
-use middle::typeck::infer::region_inference::SubSupConflict;
-use middle::typeck::infer::region_inference::SupSupConflict;
-use middle::typeck::infer::region_inference::ParamBoundFailure;
-use middle::typeck::infer::region_inference::ProcessedErrors;
-use middle::typeck::infer::region_inference::SameRegions;
 use std::cell::{Cell, RefCell};
 use std::char::from_u32;
 use std::rc::Rc;
diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/infer/glb.rs
index 671d2e3837c..4237a7af32f 100644
--- a/src/librustc/middle/typeck/infer/glb.rs
+++ b/src/librustc/middle/infer/glb.rs
@@ -8,17 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use super::combine::*;
+use super::lattice::*;
+use super::equate::Equate;
+use super::higher_ranked::HigherRankedRelations;
+use super::lub::Lub;
+use super::sub::Sub;
+use super::{cres, InferCtxt};
+use super::{TypeTrace, Subtype};
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{mod, Ty};
-use middle::typeck::infer::combine::*;
-use middle::typeck::infer::lattice::*;
-use middle::typeck::infer::equate::Equate;
-use middle::typeck::infer::higher_ranked::HigherRankedRelations;
-use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::sub::Sub;
-use middle::typeck::infer::{cres, InferCtxt};
-use middle::typeck::infer::{TypeTrace, Subtype};
 use syntax::ast::{Many, Once, MutImmutable, MutMutable};
 use syntax::ast::{NormalFn, UnsafeFn};
 use syntax::ast::{Onceness, FnStyle};
diff --git a/src/librustc/middle/typeck/infer/higher_ranked/doc.rs b/src/librustc/middle/infer/higher_ranked/doc.rs
index 2bad3616a05..2bad3616a05 100644
--- a/src/librustc/middle/typeck/infer/higher_ranked/doc.rs
+++ b/src/librustc/middle/infer/higher_ranked/doc.rs
diff --git a/src/librustc/middle/typeck/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 2f80a574bb1..95805ef8b94 100644
--- a/src/librustc/middle/typeck/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -11,10 +11,11 @@
 //! Helper routines for higher-ranked things. See the `doc` module at
 //! the end of the file for details.
 
+use super::{combine, cres, InferCtxt, HigherRankedType};
+use super::combine::Combine;
+use super::region_inference::{RegionMark};
+
 use middle::ty::{mod, Ty, replace_late_bound_regions};
-use middle::typeck::infer::{mod, combine, cres, InferCtxt};
-use middle::typeck::infer::combine::Combine;
-use middle::typeck::infer::region_inference::{RegionMark};
 use middle::ty_fold::{mod, HigherRankedFoldable, TypeFoldable};
 use syntax::codemap::Span;
 use util::nodemap::FnvHashMap;
@@ -62,7 +63,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
         let (a_prime, _) =
             self.infcx().replace_late_bound_regions_with_fresh_var(
                 self.trace().origin.span(),
-                infer::HigherRankedType,
+                HigherRankedType,
                 a);
 
         // Second, we instantiate each bound region in the supertype with a
@@ -131,10 +132,10 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
         let span = self.trace().origin.span();
         let (a_with_fresh, a_map) =
             self.infcx().replace_late_bound_regions_with_fresh_var(
-                span, infer::HigherRankedType, a);
+                span, HigherRankedType, a);
         let (b_with_fresh, _) =
             self.infcx().replace_late_bound_regions_with_fresh_var(
-                span, infer::HigherRankedType, b);
+                span, HigherRankedType, b);
 
         // Collect constraints.
         let result0 =
@@ -221,10 +222,10 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
         // Instantiate each bound region with a fresh region variable.
         let (a_with_fresh, a_map) =
             self.infcx().replace_late_bound_regions_with_fresh_var(
-                self.trace().origin.span(), infer::HigherRankedType, a);
+                self.trace().origin.span(), HigherRankedType, a);
         let (b_with_fresh, b_map) =
             self.infcx().replace_late_bound_regions_with_fresh_var(
-                self.trace().origin.span(), infer::HigherRankedType, b);
+                self.trace().origin.span(), HigherRankedType, b);
         let a_vars = var_ids(self, &a_map);
         let b_vars = var_ids(self, &b_map);
 
diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/infer/lattice.rs
index daec959d11c..dd514ebee52 100644
--- a/src/librustc/middle/typeck/infer/lattice.rs
+++ b/src/librustc/middle/infer/lattice.rs
@@ -29,12 +29,13 @@
 //! over a `LatticeValue`, which is a value defined with respect to
 //! a lattice.
 
+use super::*;
+use super::combine::*;
+use super::glb::Glb;
+use super::lub::Lub;
+
 use middle::ty::{TyVar};
 use middle::ty::{mod, Ty};
-use middle::typeck::infer::*;
-use middle::typeck::infer::combine::*;
-use middle::typeck::infer::glb::Glb;
-use middle::typeck::infer::lub::Lub;
 use util::ppaux::Repr;
 
 pub trait LatticeDir<'tcx> {
diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/infer/lub.rs
index e7bd1f3716c..f53ba571062 100644
--- a/src/librustc/middle/typeck/infer/lub.rs
+++ b/src/librustc/middle/infer/lub.rs
@@ -8,16 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use super::combine::*;
+use super::equate::Equate;
+use super::glb::Glb;
+use super::higher_ranked::HigherRankedRelations;
+use super::lattice::*;
+use super::sub::Sub;
+use super::{cres, InferCtxt};
+use super::{TypeTrace, Subtype};
+
 use middle::ty::{BuiltinBounds};
 use middle::ty::{mod, Ty};
-use middle::typeck::infer::combine::*;
-use middle::typeck::infer::equate::Equate;
-use middle::typeck::infer::glb::Glb;
-use middle::typeck::infer::higher_ranked::HigherRankedRelations;
-use middle::typeck::infer::lattice::*;
-use middle::typeck::infer::sub::Sub;
-use middle::typeck::infer::{cres, InferCtxt};
-use middle::typeck::infer::{TypeTrace, Subtype};
 use syntax::ast::{Many, Once};
 use syntax::ast::{NormalFn, UnsafeFn};
 use syntax::ast::{Onceness, FnStyle};
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index c5845b143af..c5845b143af 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
diff --git a/src/librustc/middle/typeck/infer/region_inference/doc.rs b/src/librustc/middle/infer/region_inference/doc.rs
index b4eac4c0026..686174b7306 100644
--- a/src/librustc/middle/typeck/infer/region_inference/doc.rs
+++ b/src/librustc/middle/infer/region_inference/doc.rs
@@ -371,4 +371,4 @@
 //! ### Skolemization
 //!
 //! For a discussion on skolemization and higher-ranked subtyping, please
-//! see the module `middle::typeck::infer::higher_ranked::doc`.
+//! see the module `middle::infer::higher_ranked::doc`.
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index e39fbe105dc..9155c18cb3b 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -18,14 +18,14 @@ pub use self::RegionResolutionError::*;
 pub use self::VarValue::*;
 use self::Classification::*;
 
+use super::cres;
+use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable};
+
 use middle::region;
 use middle::ty;
 use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
 use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
 use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
-use middle::typeck::infer::cres;
-use middle::typeck::infer::{RegionVariableOrigin, SubregionOrigin, TypeTrace};
-use middle::typeck::infer;
 use middle::graph;
 use middle::graph::{Direction, NodeIndex};
 use util::common::indenter;
@@ -573,7 +573,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
             }
             None => {}
         }
-        let c = self.new_region_var(infer::MiscVariable(origin.span()));
+        let c = self.new_region_var(MiscVariable(origin.span()));
         self.combine_map(t).borrow_mut().insert(vars, c);
         if self.in_snapshot() {
             self.undo_log.borrow_mut().push(AddCombination(t, vars));
diff --git a/src/librustc/middle/typeck/infer/resolve.rs b/src/librustc/middle/infer/resolve.rs
index cf5efd188ed..eaf363ffc74 100644
--- a/src/librustc/middle/typeck/infer/resolve.rs
+++ b/src/librustc/middle/infer/resolve.rs
@@ -48,12 +48,13 @@
 
 #![allow(non_upper_case_globals)]
 
+use super::{fixup_err, fres, InferCtxt};
+use super::{unresolved_int_ty,unresolved_float_ty,unresolved_ty};
+
 use middle::ty::{FloatVar, FloatVid, IntVar, IntVid, RegionVid, TyVar, TyVid};
 use middle::ty::{IntType, UintType};
 use middle::ty::{mod, Ty};
 use middle::ty_fold;
-use middle::typeck::infer::{fixup_err, fres, InferCtxt};
-use middle::typeck::infer::{unresolved_int_ty,unresolved_float_ty,unresolved_ty};
 use syntax::codemap::Span;
 use util::ppaux::{Repr, ty_to_string};
 
diff --git a/src/librustc/middle/typeck/infer/skolemize.rs b/src/librustc/middle/infer/skolemize.rs
index 62bf1d0126a..62bf1d0126a 100644
--- a/src/librustc/middle/typeck/infer/skolemize.rs
+++ b/src/librustc/middle/infer/skolemize.rs
diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/infer/sub.rs
index 65d2a513393..c470b248827 100644
--- a/src/librustc/middle/typeck/infer/sub.rs
+++ b/src/librustc/middle/infer/sub.rs
@@ -8,19 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use super::combine::*;
+use super::{cres, CresCompare};
+use super::equate::Equate;
+use super::glb::Glb;
+use super::higher_ranked::HigherRankedRelations;
+use super::InferCtxt;
+use super::lub::Lub;
+use super::{TypeTrace, Subtype};
+use super::type_variable::{SubtypeOf, SupertypeOf};
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{mod, Ty};
 use middle::ty::TyVar;
-use middle::typeck::infer::combine::*;
-use middle::typeck::infer::{cres, CresCompare};
-use middle::typeck::infer::equate::Equate;
-use middle::typeck::infer::glb::Glb;
-use middle::typeck::infer::higher_ranked::HigherRankedRelations;
-use middle::typeck::infer::InferCtxt;
-use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::{TypeTrace, Subtype};
-use middle::typeck::infer::type_variable::{SubtypeOf, SupertypeOf};
 use util::ppaux::{Repr};
 
 use syntax::ast::{Onceness, FnStyle, MutImmutable, MutMutable};
diff --git a/src/librustc/middle/typeck/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs
index 3058f09a83a..3058f09a83a 100644
--- a/src/librustc/middle/typeck/infer/type_variable.rs
+++ b/src/librustc/middle/infer/type_variable.rs
diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/infer/unify.rs
index 1b3413bfb01..6f6adb84a75 100644
--- a/src/librustc/middle/typeck/infer/unify.rs
+++ b/src/librustc/middle/infer/unify.rs
@@ -14,8 +14,8 @@ use std::kinds::marker;
 
 use middle::ty::{expected_found, IntVarValue};
 use middle::ty::{mod, Ty};
-use middle::typeck::infer::{uok, ures};
-use middle::typeck::infer::InferCtxt;
+use middle::infer::{uok, ures};
+use middle::infer::InferCtxt;
 use std::cell::RefCell;
 use std::fmt::Show;
 use syntax::ast;
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index fcc23d8ac55..523c9f33309 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -111,7 +111,7 @@ use self::VarKind::*;
 
 use middle::def::*;
 use middle::mem_categorization::Typer;
-use middle::{pat_util, typeck, ty};
+use middle::{pat_util, ty};
 use lint;
 use util::nodemap::NodeMap;
 
@@ -1156,7 +1156,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
           }
 
           ast::ExprMethodCall(_, _, ref args) => {
-            let method_call = typeck::MethodCall::expr(expr.id);
+            let method_call = ty::MethodCall::expr(expr.id);
             let method_ty = self.ir.tcx.method_map.borrow().get(&method_call).unwrap().ty;
             let diverges = ty::ty_fn_ret(method_ty) == ty::FnDiverging;
             let succ = if diverges {
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index ce166fc5de6..cd70d8e2b48 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -74,7 +74,6 @@ pub use self::categorization::*;
 use middle::def;
 use middle::region;
 use middle::ty::{mod, Ty};
-use middle::typeck;
 use util::nodemap::{DefIdMap, NodeMap};
 use util::ppaux::{ty_to_string, Repr};
 
@@ -283,7 +282,7 @@ pub type McResult<T> = Result<T, ()>;
 pub trait Typer<'tcx> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
     fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
-    fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option<Ty<'tcx>>;
+    fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
     fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
     fn is_method_call(&self, id: ast::NodeId) -> bool;
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
@@ -509,7 +508,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           }
 
           ast::ExprIndex(ref base, _) => {
-            let method_call = typeck::MethodCall::expr(expr.id());
+            let method_call = ty::MethodCall::expr(expr.id());
             match self.typer.node_method_ty(method_call) {
                 Some(method_ty) => {
                     // If this is an index implemented by a method call, then it will
@@ -890,12 +889,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                              implicit: bool)
                              -> cmt<'tcx> {
         let adjustment = match self.typer.adjustments().borrow().get(&node.id()) {
-            Some(adj) if ty::adjust_is_object(adj) => typeck::AutoObject,
-            _ if deref_cnt != 0 => typeck::AutoDeref(deref_cnt),
-            _ => typeck::NoAdjustment
+            Some(adj) if ty::adjust_is_object(adj) => ty::AutoObject,
+            _ if deref_cnt != 0 => ty::AutoDeref(deref_cnt),
+            _ => ty::NoAdjustment
         };
 
-        let method_call = typeck::MethodCall {
+        let method_call = ty::MethodCall {
             expr_id: node.id(),
             adjustment: adjustment
         };
@@ -980,7 +979,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         //! - `elt`: the AST node being indexed
         //! - `base_cmt`: the cmt of `elt`
 
-        let method_call = typeck::MethodCall::expr(elt.id());
+        let method_call = ty::MethodCall::expr(elt.id());
         let method_ty = self.typer.node_method_ty(method_call);
 
         let element_ty = match method_ty {
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 5e182ba8337..5770b601a69 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -19,8 +19,8 @@ use std::mem::replace;
 use metadata::csearch;
 use middle::{def, resolve};
 use middle::ty::{mod, Ty};
-use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam};
-use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
+use middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam};
+use middle::ty::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
 use util::nodemap::{NodeMap, NodeSet};
 
 use syntax::{ast, ast_map};
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 96e1aacb0ce..fa02c940aa7 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -17,7 +17,6 @@
 
 use middle::def;
 use middle::ty;
-use middle::typeck;
 use middle::privacy;
 use session::config;
 use util::nodemap::NodeSet;
@@ -137,9 +136,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
                 }
             }
             ast::ExprMethodCall(..) => {
-                let method_call = typeck::MethodCall::expr(expr.id);
+                let method_call = ty::MethodCall::expr(expr.id);
                 match (*self.tcx.method_map.borrow())[method_call].origin {
-                    typeck::MethodStatic(def_id) => {
+                    ty::MethodStatic(def_id) => {
                         if is_local(def_id) {
                             if self.def_id_represents_local_inlined_item(def_id) {
                                 self.worklist.push(def_id.node)
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index b958bdce0a7..f1a75f996b0 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -2654,10 +2654,34 @@ impl<'a> Resolver<'a> {
 
                     }
                     Some(_) => {
-                        // The import is unresolved. Bail out.
-                        debug!("(resolving single import) unresolved import; \
-                                bailing out");
-                        return Indeterminate;
+                        // If containing_module is the same module whose import we are resolving
+                        // and there it has an unresolved import with the same name as `source`,
+                        // then the user is actually trying to import an item that is declared
+                        // in the same scope
+                        //
+                        // e.g
+                        // use self::submodule;
+                        // pub mod submodule;
+                        //
+                        // In this case we continue as if we resolved the import and let the
+                        // check_for_conflicts_between_imports_and_items call below handle
+                        // the conflict
+                        match (module_.def_id.get(),  containing_module.def_id.get()) {
+                            (Some(id1), Some(id2)) if id1 == id2  => {
+                                if value_result.is_unknown() {
+                                    value_result = UnboundResult;
+                                }
+                                if type_result.is_unknown() {
+                                    type_result = UnboundResult;
+                                }
+                            }
+                            _ =>  {
+                                // The import is unresolved. Bail out.
+                                debug!("(resolving single import) unresolved import; \
+                                        bailing out");
+                                return Indeterminate;
+                            }
+                        }
                     }
                 }
             }
@@ -3018,7 +3042,7 @@ impl<'a> Resolver<'a> {
     fn check_for_conflicts_between_imports_and_items(&mut self,
                                                      module: &Module,
                                                      import_resolution:
-                                                     &mut ImportResolution,
+                                                     &ImportResolution,
                                                      import_span: Span,
                                                      name: Name) {
         if self.session.features.borrow().import_shadowing {
@@ -3031,8 +3055,9 @@ impl<'a> Resolver<'a> {
                  .contains_key(&name) {
             match import_resolution.type_target {
                 Some(ref target) if !target.shadowable => {
-                    let msg = format!("import `{}` conflicts with imported \
-                                       crate in this module",
+                    let msg = format!("import `{0}` conflicts with imported \
+                                       crate in this module \
+                                       (maybe you meant `use {0}::*`?)",
                                       token::get_name(name).get());
                     self.session.span_err(import_span, msg.as_slice());
                 }
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 0a3e6c20316..21f57a9d573 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -589,8 +589,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
         // type declarations and other outer declarations, not those
         // bound in *fn types*. Region substitution of the bound
         // regions that appear in a function signature is done using
-        // the specialized routine
-        // `middle::typeck::check::regionmanip::replace_late_regions_in_fn_sig()`.
+        // the specialized routine `ty::replace_late_regions()`.
         match r {
             ty::ReEarlyBound(_, space, i, region_name) => {
                 match self.substs.regions {
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index 048f394224c..1bce353cb0c 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -17,7 +17,7 @@ use super::util;
 use middle::subst;
 use middle::subst::Subst;
 use middle::ty::{mod, Ty};
-use middle::typeck::infer::{mod, InferCtxt};
+use middle::infer::{mod, InferCtxt};
 use syntax::ast;
 use syntax::codemap::DUMMY_SP;
 use util::ppaux::Repr;
diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs
index 25c86be993f..653c686ab19 100644
--- a/src/librustc/middle/traits/fulfill.rs
+++ b/src/librustc/middle/traits/fulfill.rs
@@ -10,7 +10,7 @@
 
 use middle::mem_categorization::Typer;
 use middle::ty;
-use middle::typeck::infer::InferCtxt;
+use middle::infer::InferCtxt;
 use std::collections::HashSet;
 use std::rc::Rc;
 use util::ppaux::Repr;
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index b8d915c06e0..e12ec44ad87 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -18,7 +18,7 @@ pub use self::ObligationCauseCode::*;
 use middle::mem_categorization::Typer;
 use middle::subst;
 use middle::ty::{mod, Ty};
-use middle::typeck::infer::InferCtxt;
+use middle::infer::InferCtxt;
 use std::rc::Rc;
 use std::slice::Items;
 use syntax::ast;
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 2604204d9e6..0e6a0c19f70 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -30,8 +30,8 @@ use middle::fast_reject;
 use middle::mem_categorization::Typer;
 use middle::subst::{Subst, Substs, VecPerParamSpace};
 use middle::ty::{mod, Ty};
-use middle::typeck::infer;
-use middle::typeck::infer::{InferCtxt, TypeSkolemizer};
+use middle::infer;
+use middle::infer::{InferCtxt, TypeSkolemizer};
 use middle::ty_fold::TypeFoldable;
 use std::cell::RefCell;
 use std::collections::hash_map::HashMap;
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index 1084807ef4a..1b7998a9263 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -11,7 +11,7 @@
 
 use middle::subst;
 use middle::subst::{ParamSpace, Substs, VecPerParamSpace};
-use middle::typeck::infer::InferCtxt;
+use middle::infer::InferCtxt;
 use middle::ty::{mod, Ty};
 use std::collections::HashSet;
 use std::fmt;
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 35aed356303..994f0c2090a 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -35,6 +35,9 @@ pub use self::ImplOrTraitItem::*;
 pub use self::BoundRegion::*;
 pub use self::sty::*;
 pub use self::IntVarValue::*;
+pub use self::ExprAdjustment::*;
+pub use self::vtable_origin::*;
+pub use self::MethodOrigin::*;
 
 use back::svh::Svh;
 use session::Session;
@@ -53,7 +56,6 @@ use middle::stability;
 use middle::subst::{mod, Subst, Substs, VecPerParamSpace};
 use middle::traits;
 use middle::ty;
-use middle::typeck;
 use middle::ty_fold::{mod, TypeFoldable, TypeFolder, HigherRankedFoldable};
 use middle;
 use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
@@ -90,6 +92,17 @@ pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
 
 // Data types
 
+/// The complete set of all analyses described in this module. This is
+/// produced by the driver and fed to trans and later passes.
+pub struct CrateAnalysis<'tcx> {
+    pub exp_map2: middle::resolve::ExportMap2,
+    pub exported_items: middle::privacy::ExportedItems,
+    pub public_items: middle::privacy::PublicItems,
+    pub ty_cx: ty::ctxt<'tcx>,
+    pub reachable: NodeSet,
+    pub name: String,
+}
+
 #[deriving(PartialEq, Eq, Hash)]
 pub struct field<'tcx> {
     pub name: ast::Name,
@@ -412,7 +425,161 @@ pub fn type_of_adjust<'tcx>(cx: &ctxt<'tcx>, adj: &AutoAdjustment<'tcx>) -> Opti
     }
 }
 
+#[deriving(Clone, Encodable, Decodable, PartialEq, PartialOrd, Show)]
+pub struct param_index {
+    pub space: subst::ParamSpace,
+    pub index: uint
+}
+
+#[deriving(Clone, Show)]
+pub enum MethodOrigin<'tcx> {
+    // fully statically resolved method
+    MethodStatic(ast::DefId),
+
+    // fully statically resolved unboxed closure invocation
+    MethodStaticUnboxedClosure(ast::DefId),
+
+    // method invoked on a type parameter with a bounded trait
+    MethodTypeParam(MethodParam<'tcx>),
+
+    // method invoked on a trait instance
+    MethodTraitObject(MethodObject<'tcx>),
+
+}
+
+// details for a method invoked with a receiver whose type is a type parameter
+// with a bounded trait.
+#[deriving(Clone, Show)]
+pub struct MethodParam<'tcx> {
+    // the precise trait reference that occurs as a bound -- this may
+    // be a supertrait of what the user actually typed.
+    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+
+    // index of uint in the list of methods for the trait
+    pub method_num: uint,
+}
+
+// details for a method invoked with a receiver whose type is an object
+#[deriving(Clone, Show)]
+pub struct MethodObject<'tcx> {
+    // the (super)trait containing the method to be invoked
+    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+
+    // the actual base trait id of the object
+    pub object_trait_id: ast::DefId,
+
+    // index of the method to be invoked amongst the trait's methods
+    pub method_num: uint,
+
+    // index into the actual runtime vtable.
+    // the vtable is formed by concatenating together the method lists of
+    // the base object trait and all supertraits;  this is the index into
+    // that vtable
+    pub real_index: uint,
+}
+
+#[deriving(Clone)]
+pub struct MethodCallee<'tcx> {
+    pub origin: MethodOrigin<'tcx>,
+    pub ty: Ty<'tcx>,
+    pub substs: subst::Substs<'tcx>
+}
+
+/// With method calls, we store some extra information in
+/// side tables (i.e method_map). We use
+/// MethodCall as a key to index into these tables instead of
+/// just directly using the expression's NodeId. The reason
+/// for this being that we may apply adjustments (coercions)
+/// with the resulting expression also needing to use the
+/// side tables. The problem with this is that we don't
+/// assign a separate NodeId to this new expression
+/// and so it would clash with the base expression if both
+/// needed to add to the side tables. Thus to disambiguate
+/// we also keep track of whether there's an adjustment in
+/// our key.
+#[deriving(Clone, PartialEq, Eq, Hash, Show)]
+pub struct MethodCall {
+    pub expr_id: ast::NodeId,
+    pub adjustment: ExprAdjustment
+}
+
+#[deriving(Clone, PartialEq, Eq, Hash, Show, Encodable, Decodable)]
+pub enum ExprAdjustment {
+    NoAdjustment,
+    AutoDeref(uint),
+    AutoObject
+}
+
+impl MethodCall {
+    pub fn expr(id: ast::NodeId) -> MethodCall {
+        MethodCall {
+            expr_id: id,
+            adjustment: NoAdjustment
+        }
+    }
+
+    pub fn autoobject(id: ast::NodeId) -> MethodCall {
+        MethodCall {
+            expr_id: id,
+            adjustment: AutoObject
+        }
+    }
+
+    pub fn autoderef(expr_id: ast::NodeId, autoderef: uint) -> MethodCall {
+        MethodCall {
+            expr_id: expr_id,
+            adjustment: AutoDeref(1 + autoderef)
+        }
+    }
+}
+
+// maps from an expression id that corresponds to a method call to the details
+// of the method to be invoked
+pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
 
+pub type vtable_param_res<'tcx> = Vec<vtable_origin<'tcx>>;
+
+// Resolutions for bounds of all parameters, left to right, for a given path.
+pub type vtable_res<'tcx> = VecPerParamSpace<vtable_param_res<'tcx>>;
+
+#[deriving(Clone)]
+pub enum vtable_origin<'tcx> {
+    /*
+      Statically known vtable. def_id gives the impl item
+      from whence comes the vtable, and tys are the type substs.
+      vtable_res is the vtable itself.
+     */
+    vtable_static(ast::DefId, subst::Substs<'tcx>, vtable_res<'tcx>),
+
+    /*
+      Dynamic vtable, comes from a parameter that has a bound on it:
+      fn foo<T:quux,baz,bar>(a: T) -- a's vtable would have a
+      vtable_param origin
+
+      The first argument is the param index (identifying T in the example),
+      and the second is the bound number (identifying baz)
+     */
+    vtable_param(param_index, uint),
+
+    /*
+      Vtable automatically generated for an unboxed closure. The def ID is the
+      ID of the closure expression.
+     */
+    vtable_unboxed_closure(ast::DefId),
+
+    /*
+      Asked to determine the vtable for ty_err. This is the value used
+      for the vtables of `Self` in a virtual call like `foo.bar()`
+      where `foo` is of object type. The same value is also used when
+      type errors occur.
+     */
+    vtable_error,
+}
+
+
+// For every explicit cast into an object type, maps from the cast
+// expr to the associated trait ref.
+pub type ObjectCastMap<'tcx> = RefCell<NodeMap<Rc<ty::TraitRef<'tcx>>>>;
 
 /// A restriction that certain types must be the same size. The use of
 /// `transmute` gives rise to these restrictions.
@@ -473,7 +640,7 @@ pub struct ctxt<'tcx> {
 
     /// Maps from node-id of a trait object cast (like `foo as
     /// Box<Trait>`) to the trait reference.
-    pub object_cast_map: typeck::ObjectCastMap<'tcx>,
+    pub object_cast_map: ObjectCastMap<'tcx>,
 
     pub map: ast_map::Map<'tcx>,
     pub intrinsic_defs: RefCell<DefIdMap<Ty<'tcx>>>,
@@ -548,7 +715,7 @@ pub struct ctxt<'tcx> {
     pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
     pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
 
-    pub method_map: typeck::MethodMap<'tcx>,
+    pub method_map: MethodMap<'tcx>,
 
     pub dependency_formats: RefCell<dependency_format::Dependencies>,
 
@@ -3658,7 +3825,7 @@ pub fn adjust_ty<'tcx>(cx: &ctxt<'tcx>,
                        expr_id: ast::NodeId,
                        unadjusted_ty: Ty<'tcx>,
                        adjustment: Option<&AutoAdjustment<'tcx>>,
-                       method_type: |typeck::MethodCall| -> Option<Ty<'tcx>>)
+                       method_type: |MethodCall| -> Option<Ty<'tcx>>)
                        -> Ty<'tcx> {
 
     if let ty_err = unadjusted_ty.sty {
@@ -3699,7 +3866,7 @@ pub fn adjust_ty<'tcx>(cx: &ctxt<'tcx>,
 
                     if !ty::type_is_error(adjusted_ty) {
                         for i in range(0, adj.autoderefs) {
-                            let method_call = typeck::MethodCall::autoderef(expr_id, i);
+                            let method_call = MethodCall::autoderef(expr_id, i);
                             match method_type(method_call) {
                                 Some(method_ty) => {
                                     if let ty::FnConverging(result_type) = ty_fn_ret(method_ty) {
@@ -3830,7 +3997,7 @@ pub enum ExprKind {
 }
 
 pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
-    if tcx.method_map.borrow().contains_key(&typeck::MethodCall::expr(expr.id)) {
+    if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) {
         // Overloaded operations are generally calls, and hence they are
         // generated via DPS, but there are a few exceptions:
         return match expr.node {
@@ -5747,7 +5914,7 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
         Ok(ty::node_id_to_type(self, id))
     }
 
-    fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option<Ty<'tcx>> {
+    fn node_method_ty(&self, method_call: MethodCall) -> Option<Ty<'tcx>> {
         self.method_map.borrow().get(&method_call).map(|method| method.ty)
     }
 
@@ -5756,7 +5923,7 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
     }
 
     fn is_method_call(&self, id: ast::NodeId) -> bool {
-        self.method_map.borrow().contains_key(&typeck::MethodCall::expr(id))
+        self.method_map.borrow().contains_key(&MethodCall::expr(id))
     }
 
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
@@ -6010,3 +6177,55 @@ impl<'tcx> Repr<'tcx> for TyTrait<'tcx> {
                 self.bounds.repr(tcx))
     }
 }
+
+impl<'tcx> Repr<'tcx> for vtable_origin<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        match *self {
+            vtable_static(def_id, ref tys, ref vtable_res) => {
+                format!("vtable_static({}:{}, {}, {})",
+                        def_id,
+                        ty::item_path_str(tcx, def_id),
+                        tys.repr(tcx),
+                        vtable_res.repr(tcx))
+            }
+
+            vtable_param(x, y) => {
+                format!("vtable_param({}, {})", x, y)
+            }
+
+            vtable_unboxed_closure(def_id) => {
+                format!("vtable_unboxed_closure({})", def_id)
+            }
+
+            vtable_error => {
+                format!("vtable_error")
+            }
+        }
+    }
+}
+
+pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                            trait_ref: &ty::TraitRef<'tcx>,
+                                            method: &ty::Method<'tcx>)
+                                            -> subst::Substs<'tcx>
+{
+    /*!
+     * Substitutes the values for the receiver's type parameters
+     * that are found in method, leaving the method's type parameters
+     * intact.
+     */
+
+    let meth_tps: Vec<Ty> =
+        method.generics.types.get_slice(subst::FnSpace)
+              .iter()
+              .map(|def| ty::mk_param_from_def(tcx, def))
+              .collect();
+    let meth_regions: Vec<ty::Region> =
+        method.generics.regions.get_slice(subst::FnSpace)
+              .iter()
+              .map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
+                                          def.index, def.name))
+              .collect();
+    trait_ref.substs.clone().with_method(meth_tps, meth_regions)
+}
+
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index de9eb426498..77092025349 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -38,7 +38,6 @@ use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::{mod, Ty};
 use middle::traits;
-use middle::typeck;
 use std::rc::Rc;
 use syntax::owned_slice::OwnedSlice;
 use util::ppaux::Repr;
@@ -304,23 +303,23 @@ impl<'tcx> TypeFoldable<'tcx> for ty::AutoRef<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for typeck::MethodOrigin<'tcx> {
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> typeck::MethodOrigin<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for ty::MethodOrigin<'tcx> {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::MethodOrigin<'tcx> {
         match *self {
-            typeck::MethodStatic(def_id) => {
-                typeck::MethodStatic(def_id)
+            ty::MethodStatic(def_id) => {
+                ty::MethodStatic(def_id)
             }
-            typeck::MethodStaticUnboxedClosure(def_id) => {
-                typeck::MethodStaticUnboxedClosure(def_id)
+            ty::MethodStaticUnboxedClosure(def_id) => {
+                ty::MethodStaticUnboxedClosure(def_id)
             }
-            typeck::MethodTypeParam(ref param) => {
-                typeck::MethodTypeParam(typeck::MethodParam {
+            ty::MethodTypeParam(ref param) => {
+                ty::MethodTypeParam(ty::MethodParam {
                     trait_ref: param.trait_ref.fold_with(folder),
                     method_num: param.method_num
                 })
             }
-            typeck::MethodTraitObject(ref object) => {
-                typeck::MethodTraitObject(typeck::MethodObject {
+            ty::MethodTraitObject(ref object) => {
+                ty::MethodTraitObject(ty::MethodObject {
                     trait_ref: object.trait_ref.fold_with(folder),
                     object_trait_id: object.object_trait_id,
                     method_num: object.method_num,
@@ -331,22 +330,22 @@ impl<'tcx> TypeFoldable<'tcx> for typeck::MethodOrigin<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for typeck::vtable_origin<'tcx> {
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> typeck::vtable_origin<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for ty::vtable_origin<'tcx> {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::vtable_origin<'tcx> {
         match *self {
-            typeck::vtable_static(def_id, ref substs, ref origins) => {
+            ty::vtable_static(def_id, ref substs, ref origins) => {
                 let r_substs = substs.fold_with(folder);
                 let r_origins = origins.fold_with(folder);
-                typeck::vtable_static(def_id, r_substs, r_origins)
+                ty::vtable_static(def_id, r_substs, r_origins)
             }
-            typeck::vtable_param(n, b) => {
-                typeck::vtable_param(n, b)
+            ty::vtable_param(n, b) => {
+                ty::vtable_param(n, b)
             }
-            typeck::vtable_unboxed_closure(def_id) => {
-                typeck::vtable_unboxed_closure(def_id)
+            ty::vtable_unboxed_closure(def_id) => {
+                ty::vtable_unboxed_closure(def_id)
             }
-            typeck::vtable_error => {
-                typeck::vtable_error
+            ty::vtable_error => {
+                ty::vtable_error
             }
         }
     }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 33de2c9abe9..cbc9dd9145b 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -114,6 +114,59 @@ pub struct Options {
     pub alt_std_name: Option<String>
 }
 
+pub enum Input {
+    /// Load source from file
+    File(Path),
+    /// The string is the source
+    Str(String)
+}
+
+impl Input {
+    pub fn filestem(&self) -> String {
+        match *self {
+            Input::File(ref ifile) => ifile.filestem_str().unwrap().to_string(),
+            Input::Str(_) => "rust_out".to_string(),
+        }
+    }
+}
+
+#[deriving(Clone)]
+pub struct OutputFilenames {
+    pub out_directory: Path,
+    pub out_filestem: String,
+    pub single_output_file: Option<Path>,
+    pub extra: String,
+}
+
+impl OutputFilenames {
+    pub fn path(&self, flavor: OutputType) -> Path {
+        match self.single_output_file {
+            Some(ref path) => return path.clone(),
+            None => {}
+        }
+        self.temp_path(flavor)
+    }
+
+    pub fn temp_path(&self, flavor: OutputType) -> Path {
+        let base = self.out_directory.join(self.filestem());
+        match flavor {
+            OutputTypeBitcode => base.with_extension("bc"),
+            OutputTypeAssembly => base.with_extension("s"),
+            OutputTypeLlvmAssembly => base.with_extension("ll"),
+            OutputTypeObject => base.with_extension("o"),
+            OutputTypeExe => base,
+        }
+    }
+
+    pub fn with_extension(&self, extension: &str) -> Path {
+        self.out_directory.join(self.filestem()).with_extension(extension)
+    }
+
+    pub fn filestem(&self) -> String {
+        format!("{}{}", self.out_filestem, self.extra)
+    }
+}
+
 pub fn host_triple() -> &'static str {
     // Get the host triple out of the build environment. This ensures that our
     // idea of the host triple is the same as for the set of libraries we've
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index b739a97f734..1283e89c29d 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -23,8 +23,6 @@ use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
 use middle::ty::{ty_unboxed_closure};
 use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
 use middle::ty;
-use middle::typeck;
-use middle::typeck::check::regionmanip;
 
 use std::rc::Rc;
 use syntax::abi;
@@ -1018,7 +1016,7 @@ impl<'tcx> Repr<'tcx> for ty::FnOutput<'tcx> {
     }
 }
 
-impl<'tcx> Repr<'tcx> for typeck::MethodCallee<'tcx> {
+impl<'tcx> Repr<'tcx> for ty::MethodCallee<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         format!("MethodCallee {{origin: {}, ty: {}, {}}}",
                 self.origin.repr(tcx),
@@ -1027,26 +1025,26 @@ impl<'tcx> Repr<'tcx> for typeck::MethodCallee<'tcx> {
     }
 }
 
-impl<'tcx> Repr<'tcx> for typeck::MethodOrigin<'tcx> {
+impl<'tcx> Repr<'tcx> for ty::MethodOrigin<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         match self {
-            &typeck::MethodStatic(def_id) => {
+            &ty::MethodStatic(def_id) => {
                 format!("MethodStatic({})", def_id.repr(tcx))
             }
-            &typeck::MethodStaticUnboxedClosure(def_id) => {
+            &ty::MethodStaticUnboxedClosure(def_id) => {
                 format!("MethodStaticUnboxedClosure({})", def_id.repr(tcx))
             }
-            &typeck::MethodTypeParam(ref p) => {
+            &ty::MethodTypeParam(ref p) => {
                 p.repr(tcx)
             }
-            &typeck::MethodTraitObject(ref p) => {
+            &ty::MethodTraitObject(ref p) => {
                 p.repr(tcx)
             }
         }
     }
 }
 
-impl<'tcx> Repr<'tcx> for typeck::MethodParam<'tcx> {
+impl<'tcx> Repr<'tcx> for ty::MethodParam<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         format!("MethodParam({},{})",
                 self.trait_ref.repr(tcx),
@@ -1054,7 +1052,7 @@ impl<'tcx> Repr<'tcx> for typeck::MethodParam<'tcx> {
     }
 }
 
-impl<'tcx> Repr<'tcx> for typeck::MethodObject<'tcx> {
+impl<'tcx> Repr<'tcx> for ty::MethodObject<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         format!("MethodObject({},{},{})",
                 self.trait_ref.repr(tcx),
@@ -1293,25 +1291,6 @@ impl<'tcx> Repr<'tcx> for ty::ExplicitSelfCategory {
     }
 }
 
-
-impl<'tcx> Repr<'tcx> for regionmanip::WfConstraint<'tcx> {
-    fn repr(&self, tcx: &ctxt) -> String {
-        match *self {
-            regionmanip::RegionSubRegionConstraint(_, r_a, r_b) => {
-                format!("RegionSubRegionConstraint({}, {})",
-                        r_a.repr(tcx),
-                        r_b.repr(tcx))
-            }
-
-            regionmanip::RegionSubParamConstraint(_, r, p) => {
-                format!("RegionSubParamConstraint({}, {})",
-                        r.repr(tcx),
-                        p.repr(tcx))
-            }
-        }
-    }
-}
-
 impl<'tcx> UserString<'tcx> for ParamTy {
     fn user_string(&self, tcx: &ctxt) -> String {
         let id = self.idx;
diff --git a/src/librustc_trans/driver/driver.rs b/src/librustc_driver/driver.rs
index d3281ae1c19..437b0257a97 100644
--- a/src/librustc_trans/driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -8,26 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::Input::*;
-
-use back::link;
-use back::write;
-use session::Session;
-use session::config;
-use lint;
-use llvm::{ContextRef, ModuleRef};
-use metadata::common::LinkMeta;
-use metadata::creader;
-use middle::{stability, ty, typeck, reachable};
-use middle::dependency_format;
-use middle;
-use plugin::load::Plugins;
-use plugin::registry::Registry;
-use plugin;
-use trans;
-
-use util::common::time;
-use util::nodemap::{NodeSet};
+use rustc::session::Session;
+use rustc::session::config::{mod, Input, OutputFilenames};
+use rustc::lint;
+use rustc::metadata::creader;
+use rustc::middle::{stability, ty, reachable};
+use rustc::middle::dependency_format;
+use rustc::middle;
+use rustc::plugin::load::Plugins;
+use rustc::plugin::registry::Registry;
+use rustc::plugin;
+use rustc::util::common::time;
+use rustc_trans::back::link;
+use rustc_trans::back::write;
+use rustc_trans::save;
+use rustc_trans::trans;
+use rustc_typeck as typeck;
 
 use serialize::{json, Encodable};
 
@@ -35,7 +31,6 @@ use std::io;
 use std::io::fs;
 use std::os;
 use arena::TypedArena;
-use save;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::attr;
@@ -113,36 +108,19 @@ pub fn anon_src() -> String {
 pub fn source_name(input: &Input) -> String {
     match *input {
         // FIXME (#9639): This needs to handle non-utf8 paths
-        FileInput(ref ifile) => ifile.as_str().unwrap().to_string(),
-        StrInput(_) => anon_src()
+        Input::File(ref ifile) => ifile.as_str().unwrap().to_string(),
+        Input::Str(_) => anon_src()
     }
 }
 
-pub enum Input {
-    /// Load source from file
-    FileInput(Path),
-    /// The string is the source
-    StrInput(String)
-}
-
-impl Input {
-    fn filestem(&self) -> String {
-        match *self {
-            FileInput(ref ifile) => ifile.filestem_str().unwrap().to_string(),
-            StrInput(_) => "rust_out".to_string(),
-        }
-    }
-}
-
-
 pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
     -> ast::Crate {
     let krate = time(sess.time_passes(), "parsing", (), |_| {
         match *input {
-            FileInput(ref file) => {
+            Input::File(ref file) => {
                 parse::parse_crate_from_file(&(*file), cfg.clone(), &sess.parse_sess)
             }
-            StrInput(ref src) => {
+            Input::Str(ref src) => {
                 parse::parse_crate_from_source_str(anon_src().to_string(),
                                                    src.to_string(),
                                                    cfg.clone(),
@@ -342,23 +320,13 @@ pub fn assign_node_ids_and_map<'ast>(sess: &Session,
     map
 }
 
-pub struct CrateAnalysis<'tcx> {
-    pub exp_map2: middle::resolve::ExportMap2,
-    pub exported_items: middle::privacy::ExportedItems,
-    pub public_items: middle::privacy::PublicItems,
-    pub ty_cx: ty::ctxt<'tcx>,
-    pub reachable: NodeSet,
-    pub name: String,
-}
-
-
 /// Run the resolution, typechecking, region checking and other
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
 pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
                                          ast_map: ast_map::Map<'tcx>,
                                          type_arena: &'tcx TypedArena<ty::TyS<'tcx>>,
-                                         name: String) -> CrateAnalysis<'tcx> {
+                                         name: String) -> ty::CrateAnalysis<'tcx> {
     let time_passes = sess.time_passes();
     let krate = ast_map.krate();
 
@@ -473,7 +441,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     time(time_passes, "lint checking", (), |_|
          lint::check_crate(&ty_cx, &exported_items));
 
-    CrateAnalysis {
+    ty::CrateAnalysis {
         exp_map2: exp_map2,
         ty_cx: ty_cx,
         exported_items: exported_items,
@@ -485,7 +453,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
 
 pub fn phase_save_analysis(sess: &Session,
                            krate: &ast::Crate,
-                           analysis: &CrateAnalysis,
+                           analysis: &ty::CrateAnalysis,
                            odir: &Option<Path>) {
     if (sess.opts.debugging_opts & config::SAVE_ANALYSIS) == 0 {
         return;
@@ -494,25 +462,10 @@ pub fn phase_save_analysis(sess: &Session,
          save::process_crate(sess, krate, analysis, odir));
 }
 
-pub struct ModuleTranslation {
-    pub llcx: ContextRef,
-    pub llmod: ModuleRef,
-}
-
-pub struct CrateTranslation {
-    pub modules: Vec<ModuleTranslation>,
-    pub metadata_module: ModuleTranslation,
-    pub link: LinkMeta,
-    pub metadata: Vec<u8>,
-    pub reachable: Vec<String>,
-    pub crate_formats: dependency_format::Dependencies,
-    pub no_builtins: bool,
-}
-
 /// Run the translation phase to LLVM, after which the AST and analysis can
 /// be discarded.
-pub fn phase_4_translate_to_llvm<'tcx>(analysis: CrateAnalysis<'tcx>)
-                                       -> (ty::ctxt<'tcx>, CrateTranslation) {
+pub fn phase_4_translate_to_llvm<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
+                                       -> (ty::ctxt<'tcx>, trans::CrateTranslation) {
     let time_passes = analysis.ty_cx.sess.time_passes();
 
     time(time_passes, "resolving dependency formats", (), |_|
@@ -520,13 +473,13 @@ pub fn phase_4_translate_to_llvm<'tcx>(analysis: CrateAnalysis<'tcx>)
 
     // Option dance to work around the lack of stack once closures.
     time(time_passes, "translation", analysis, |analysis|
-         trans::base::trans_crate(analysis))
+         trans::trans_crate(analysis))
 }
 
 /// Run LLVM itself, producing a bitcode file, assembly file or object file
 /// as a side effect.
 pub fn phase_5_run_llvm_passes(sess: &Session,
-                               trans: &CrateTranslation,
+                               trans: &trans::CrateTranslation,
                                outputs: &OutputFilenames) {
     if sess.opts.cg.no_integrated_as {
         let output_type = config::OutputTypeAssembly;
@@ -554,7 +507,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
 /// Run the linker on any artifacts that resulted from the LLVM run.
 /// This should produce either a finished executable or library.
 pub fn phase_6_link_output(sess: &Session,
-                           trans: &CrateTranslation,
+                           trans: &trans::CrateTranslation,
                            outputs: &OutputFilenames) {
     let old_path = os::getenv("PATH").unwrap_or_else(||String::new());
     let mut new_path = sess.host_filesearch().get_tools_search_paths();
@@ -639,8 +592,8 @@ fn write_out_deps(sess: &Session,
         // Use default filename: crate source filename with extension replaced
         // by ".d"
         (true, None) => match *input {
-            FileInput(..) => outputs.with_extension("d"),
-            StrInput(..) => {
+            Input::File(..) => outputs.with_extension("d"),
+            Input::Str(..) => {
                 sess.warn("can not write --dep-info without a filename \
                            when compiling stdin.");
                 return
@@ -751,43 +704,6 @@ pub fn collect_crate_metadata(session: &Session,
     session.opts.cg.metadata.clone()
 }
 
-#[deriving(Clone)]
-pub struct OutputFilenames {
-    pub out_directory: Path,
-    pub out_filestem: String,
-    pub single_output_file: Option<Path>,
-    extra: String,
-}
-
-impl OutputFilenames {
-    pub fn path(&self, flavor: config::OutputType) -> Path {
-        match self.single_output_file {
-            Some(ref path) => return path.clone(),
-            None => {}
-        }
-        self.temp_path(flavor)
-    }
-
-    pub fn temp_path(&self, flavor: config::OutputType) -> Path {
-        let base = self.out_directory.join(self.filestem());
-        match flavor {
-            config::OutputTypeBitcode => base.with_extension("bc"),
-            config::OutputTypeAssembly => base.with_extension("s"),
-            config::OutputTypeLlvmAssembly => base.with_extension("ll"),
-            config::OutputTypeObject => base.with_extension("o"),
-            config::OutputTypeExe => base,
-        }
-    }
-
-    pub fn with_extension(&self, extension: &str) -> Path {
-        self.out_directory.join(self.filestem()).with_extension(extension)
-    }
-
-    fn filestem(&self) -> String {
-        format!("{}{}", self.out_filestem, self.extra)
-    }
-}
-
 pub fn build_output_filenames(input: &Input,
                               odir: &Option<Path>,
                               ofile: &Option<Path>,
diff --git a/src/librustc_trans/driver/mod.rs b/src/librustc_driver/lib.rs
index 658be9169af..33c009cf329 100644
--- a/src/librustc_trans/driver/mod.rs
+++ b/src/librustc_driver/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,15 +8,46 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use syntax::diagnostic;
+//! The Rust compiler.
+//!
+//! # Note
+//!
+//! This API is completely unstable and subject to change.
+
+#![crate_name = "rustc_driver"]
+#![experimental]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+      html_root_url = "http://doc.rust-lang.org/nightly/")]
+
+#![feature(default_type_params, globs, if_let, import_shadowing, macro_rules, phase, quote)]
+#![feature(slicing_syntax, unsafe_destructor)]
+#![feature(rustc_diagnostic_macros)]
+
+extern crate arena;
+extern crate flate;
+extern crate getopts;
+extern crate graphviz;
+extern crate libc;
+extern crate rustc;
+extern crate rustc_typeck;
+extern crate rustc_back;
+extern crate rustc_trans;
+#[phase(plugin, link)] extern crate log;
+#[phase(plugin, link)] extern crate syntax;
+extern crate serialize;
+extern crate "rustc_llvm" as llvm;
 
-use back::link;
-use driver::driver::{Input, FileInput, StrInput};
-use session::{config, Session, build_session};
-use lint::Lint;
-use lint;
-use metadata;
+pub use syntax::diagnostic;
 
+use rustc_trans::back::link;
+use rustc::session::{config, Session, build_session};
+use rustc::session::config::Input;
+use rustc::lint::Lint;
+use rustc::lint;
+use rustc::metadata;
 use rustc::DIAGNOSTICS;
 
 use std::any::AnyRefExt;
@@ -24,14 +55,15 @@ use std::io;
 use std::os;
 use std::task::TaskBuilder;
 
-use session::early_error;
+use rustc::session::early_error;
 
 use syntax::ast;
 use syntax::parse;
 use syntax::diagnostic::Emitter;
 use syntax::diagnostics;
 
-use getopts;
+#[cfg(test)]
+pub mod test;
 
 pub mod driver;
 pub mod pretty;
@@ -89,9 +121,9 @@ fn run_compiler(args: &[String]) {
             if ifile == "-" {
                 let contents = io::stdin().read_to_end().unwrap();
                 let src = String::from_utf8(contents).unwrap();
-                (StrInput(src), None)
+                (Input::Str(src), None)
             } else {
-                (FileInput(Path::new(ifile)), Some(Path::new(ifile)))
+                (Input::File(Path::new(ifile)), Some(Path::new(ifile)))
             }
         }
         _ => early_error("multiple input filenames provided")
@@ -116,11 +148,11 @@ fn run_compiler(args: &[String]) {
     let r = matches.opt_strs("Z");
     if r.contains(&("ls".to_string())) {
         match input {
-            FileInput(ref ifile) => {
+            Input::File(ref ifile) => {
                 let mut stdout = io::stdout();
                 list_metadata(&sess, &(*ifile), &mut stdout).unwrap();
             }
-            StrInput(_) => {
+            Input::Str(_) => {
                 early_error("can not list metadata for stdin");
             }
         }
@@ -411,12 +443,12 @@ fn print_crate_info(sess: &Session,
 fn parse_crate_attrs(sess: &Session, input: &Input) ->
                      Vec<ast::Attribute> {
     let result = match *input {
-        FileInput(ref ifile) => {
+        Input::File(ref ifile) => {
             parse::parse_crate_attrs_from_file(ifile,
                                                Vec::new(),
                                                &sess.parse_sess)
         }
-        StrInput(ref src) => {
+        Input::Str(ref src) => {
             parse::parse_crate_attrs_from_source_str(
                 driver::anon_src().to_string(),
                 src.to_string(),
@@ -438,13 +470,7 @@ pub fn list_metadata(sess: &Session, path: &Path,
 /// The diagnostic emitter yielded to the procedure should be used for reporting
 /// errors of the compiler.
 pub fn monitor(f: proc():Send) {
-    // FIXME: This is a hack for newsched since it doesn't support split stacks.
-    // rustc needs a lot of stack! When optimizations are disabled, it needs
-    // even *more* stack than usual as well.
-    #[cfg(rtopt)]
-    static STACK_SIZE: uint = 6000000;  // 6MB
-    #[cfg(not(rtopt))]
-    static STACK_SIZE: uint = 20000000; // 20MB
+    static STACK_SIZE: uint = 32000000; // 32MB
 
     let (tx, rx) = channel();
     let w = io::ChanWriter::new(tx);
@@ -507,3 +533,9 @@ pub fn monitor(f: proc():Send) {
     }
 }
 
+pub fn main() {
+    let args = std::os::args();
+    let result = run(args);
+    std::os::set_exit_status(result);
+}
+
diff --git a/src/librustc_driver/mod.rs b/src/librustc_driver/mod.rs
new file mode 100644
index 00000000000..1fbbc9c0521
--- /dev/null
+++ b/src/librustc_driver/mod.rs
@@ -0,0 +1,10 @@
+// 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.
+
diff --git a/src/librustc_trans/driver/pretty.rs b/src/librustc_driver/pretty.rs
index 7bb83d7c2a8..b6441ab4944 100644
--- a/src/librustc_trans/driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -15,18 +15,18 @@ pub use self::PpSourceMode::*;
 pub use self::PpMode::*;
 use self::NodesMatchingUII::*;
 
-use back::link;
+use rustc_trans::back::link;
 
-use session::{config, Session};
-use driver::driver::{mod, CrateAnalysis};
+use driver;
 
-use middle::ty;
-use middle::borrowck::{mod, FnPartsWithCFG};
-use middle::borrowck::graphviz as borrowck_dot;
-use middle::cfg;
-use middle::cfg::graphviz::LabelledCFG;
-
-use util::ppaux;
+use rustc::middle::ty;
+use rustc::middle::borrowck::{mod, FnPartsWithCFG};
+use rustc::middle::borrowck::graphviz as borrowck_dot;
+use rustc::middle::cfg;
+use rustc::middle::cfg::graphviz::LabelledCFG;
+use rustc::session::Session;
+use rustc::session::config::{mod, Input};
+use rustc::util::ppaux;
 
 use syntax::ast;
 use syntax::ast_map::{mod, blocks, NodePrinter};
@@ -242,7 +242,7 @@ impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
 
 
 struct TypedAnnotation<'tcx> {
-    analysis: CrateAnalysis<'tcx>,
+    analysis: ty::CrateAnalysis<'tcx>,
 }
 
 impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
@@ -409,7 +409,7 @@ fn needs_expansion(ppm: &PpMode) -> bool {
 
 pub fn pretty_print_input(sess: Session,
                           cfg: ast::CrateConfig,
-                          input: &driver::Input,
+                          input: &Input,
                           ppm: PpMode,
                           opt_uii: Option<UserIdentifiedItem>,
                           ofile: Option<Path>) {
@@ -536,7 +536,7 @@ pub fn pretty_print_input(sess: Session,
 }
 
 fn print_flowgraph<W:io::Writer>(variants: Vec<borrowck_dot::Variant>,
-                                 analysis: CrateAnalysis,
+                                 analysis: ty::CrateAnalysis,
                                  code: blocks::Code,
                                  mut out: W) -> io::IoResult<()> {
     let ty_cx = &analysis.ty_cx;
diff --git a/src/librustc_trans/test.rs b/src/librustc_driver/test.rs
index 41fbe855769..9404802cb68 100644
--- a/src/librustc_trans/test.rs
+++ b/src/librustc_driver/test.rs
@@ -10,28 +10,28 @@
 
 //! # Standalone Tests for the Inference Module
 
-use driver::diagnostic;
-use driver::diagnostic::Emitter;
-use driver::driver;
-use middle::lang_items;
-use middle::region::{mod, CodeExtent};
-use middle::resolve;
-use middle::resolve_lifetime;
-use middle::stability;
-use middle::subst;
-use middle::subst::Subst;
-use middle::ty::{mod, Ty};
-use middle::typeck::infer::combine::Combine;
-use middle::typeck::infer;
-use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::glb::Glb;
-use session::{mod,config};
+use diagnostic;
+use diagnostic::Emitter;
+use driver;
+use rustc_typeck::middle::lang_items;
+use rustc_typeck::middle::region::{mod, CodeExtent};
+use rustc_typeck::middle::resolve;
+use rustc_typeck::middle::resolve_lifetime;
+use rustc_typeck::middle::stability;
+use rustc_typeck::middle::subst;
+use rustc_typeck::middle::subst::Subst;
+use rustc_typeck::middle::ty::{mod, Ty};
+use rustc_typeck::middle::infer::combine::Combine;
+use rustc_typeck::middle::infer;
+use rustc_typeck::middle::infer::lub::Lub;
+use rustc_typeck::middle::infer::glb::Glb;
+use rustc_typeck::util::ppaux::{ty_to_string, Repr, UserString};
+use rustc::session::{mod,config};
 use syntax::{abi, ast, ast_map, ast_util};
 use syntax::codemap;
 use syntax::codemap::{Span, CodeMap, DUMMY_SP};
 use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
 use syntax::parse::token;
-use util::ppaux::{ty_to_string, Repr, UserString};
 
 use arena::TypedArena;
 
@@ -108,7 +108,7 @@ fn test_env(source_string: &str,
 
     let sess = session::build_session_(options, None, span_diagnostic_handler);
     let krate_config = Vec::new();
-    let input = driver::StrInput(source_string.to_string());
+    let input = config::Input::Str(source_string.to_string());
     let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
     let krate = driver::phase_2_configure_and_expand(&sess, krate, "test", None)
                     .expect("phase 2 aborted");
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index d8cdffe2100..6057f9d9081 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -13,15 +13,13 @@ use super::archive;
 use super::rpath;
 use super::rpath::RPathConfig;
 use super::svh::Svh;
-use driver::driver::{CrateTranslation, OutputFilenames, Input, FileInput};
 use session::config;
 use session::config::NoDebugInfo;
-use session::config::{OutputTypeBitcode, OutputTypeExe, OutputTypeObject};
+use session::config::{OutputFilenames, Input, OutputTypeBitcode, OutputTypeExe, OutputTypeObject};
 use session::Session;
 use metadata::common::LinkMeta;
 use metadata::{encoder, cstore, filesearch, csearch, creader};
-use trans::context::CrateContext;
-use trans::common::gensym_name;
+use trans::{CrateContext, CrateTranslation, gensym_name};
 use middle::ty::{mod, Ty};
 use util::common::time;
 use util::ppaux;
@@ -156,7 +154,7 @@ pub fn find_crate_name(sess: Option<&Session>,
     if let Some((attr, s)) = attr_crate_name {
         return validate(s.get().to_string(), Some(attr.span));
     }
-    if let FileInput(ref path) = *input {
+    if let Input::File(ref path) = *input {
         if let Some(s) = path.filestem_str() {
             return validate(s.to_string(), None);
         }
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index b923bb076c3..e5ffe2675d6 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -10,13 +10,13 @@
 
 use back::lto;
 use back::link::{get_cc_prog, remove};
-use driver::driver::{CrateTranslation, ModuleTranslation, OutputFilenames};
-use session::config::{NoDebugInfo, Passes, SomePasses, AllPasses};
+use session::config::{OutputFilenames, NoDebugInfo, Passes, SomePasses, AllPasses};
 use session::Session;
 use session::config;
 use llvm;
 use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
 use llvm::SMDiagnosticRef;
+use trans::{CrateTranslation, ModuleTranslation};
 use util::common::time;
 use syntax::codemap;
 use syntax::diagnostic;
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 4dc8c4d1736..4e25921e0b2 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -65,17 +65,7 @@ pub mod back {
 
 pub mod trans;
 pub mod save;
-pub mod driver;
 
 pub mod lib {
     pub use llvm;
 }
-
-pub fn main() {
-    let args = std::os::args();
-    let result = driver::run(args);
-    std::os::set_exit_status(result);
-}
-
-#[cfg(test)]
-pub mod test;
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 7a41be1dbe4..1482422b8d0 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -27,10 +27,9 @@
 //! the format of the output away from extracting it from the compiler.
 //! DxrVisitor walks the AST and processes it.
 
-use driver::driver::CrateAnalysis;
 use session::Session;
 
-use middle::{def, typeck};
+use middle::def;
 use middle::ty::{mod, Ty};
 
 use std::cell::Cell;
@@ -68,7 +67,7 @@ fn generated_code(span: Span) -> bool {
 
 struct DxrVisitor<'l, 'tcx: 'l> {
     sess: &'l Session,
-    analysis: &'l CrateAnalysis<'tcx>,
+    analysis: &'l ty::CrateAnalysis<'tcx>,
 
     collected_paths: Vec<(NodeId, ast::Path, bool, recorder::Row)>,
     collecting: bool,
@@ -912,10 +911,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                            ex: &ast::Expr,
                            args: &Vec<P<ast::Expr>>) {
         let method_map = self.analysis.ty_cx.method_map.borrow();
-        let method_callee = &(*method_map)[typeck::MethodCall::expr(ex.id)];
+        let method_callee = &(*method_map)[ty::MethodCall::expr(ex.id)];
         let (def_id, decl_id) = match method_callee.origin {
-            typeck::MethodStatic(def_id) |
-            typeck::MethodStaticUnboxedClosure(def_id) => {
+            ty::MethodStatic(def_id) |
+            ty::MethodStaticUnboxedClosure(def_id) => {
                 // method invoked on an object with a concrete type (not a static method)
                 let decl_id =
                     match ty::trait_item_of_item(&self.analysis.ty_cx,
@@ -936,14 +935,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                 };
                 (Some(def_id), decl_id)
             }
-            typeck::MethodTypeParam(ref mp) => {
+            ty::MethodTypeParam(ref mp) => {
                 // method invoked on a type parameter
                 let trait_item = ty::trait_item(&self.analysis.ty_cx,
                                                 mp.trait_ref.def_id,
                                                 mp.method_num);
                 (None, Some(trait_item.def_id()))
             }
-            typeck::MethodTraitObject(ref mo) => {
+            ty::MethodTraitObject(ref mo) => {
                 // method invoked on a trait instance
                 let trait_item = ty::trait_item(&self.analysis.ty_cx,
                                                 mo.trait_ref.def_id,
@@ -1473,7 +1472,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
 
 pub fn process_crate(sess: &Session,
                      krate: &ast::Crate,
-                     analysis: &CrateAnalysis,
+                     analysis: &ty::CrateAnalysis,
                      odir: &Option<Path>) {
     if generated_code(krate.span) {
         return;
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 84a6b59934f..9d0e096c71d 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -28,9 +28,11 @@
 pub use self::ValueOrigin::*;
 pub use self::scalar_type::*;
 
+use super::CrateTranslation;
+use super::ModuleTranslation;
+
 use back::link::{mangle_exported_name};
 use back::{link, abi};
-use driver::driver::{CrateAnalysis, CrateTranslation, ModuleTranslation};
 use lint;
 use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
 use llvm;
@@ -1078,12 +1080,6 @@ pub fn store_ty(cx: Block, v: ValueRef, dst: ValueRef, t: Ty) {
     };
 }
 
-pub fn ignore_lhs(_bcx: Block, local: &ast::Local) -> bool {
-    match local.pat.node {
-        ast::PatWild(ast::PatWildSingle) => true, _ => false
-    }
-}
-
 pub fn init_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, local: &ast::Local)
                               -> Block<'blk, 'tcx> {
     debug!("init_local(bcx={}, local.id={})", bcx.to_str(), local.id);
@@ -2916,12 +2912,6 @@ fn register_method(ccx: &CrateContext, id: ast::NodeId,
     llfn
 }
 
-pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef {
-    unsafe {
-        return llvm::LLVMConstPtrToInt(v, ccx.int_type().to_ref());
-    }
-}
-
 pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
                                             ie: encoder::EncodeInlinedItem<'a>)
                                             -> encoder::EncodeParams<'a, 'tcx> {
@@ -3055,9 +3045,9 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
     }
 }
 
-pub fn trans_crate<'tcx>(analysis: CrateAnalysis<'tcx>)
+pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
                          -> (ty::ctxt<'tcx>, CrateTranslation) {
-    let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
+    let ty::CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
     let krate = tcx.map.krate();
 
     // Before we touch LLVM, make sure that multithreading is enabled.
diff --git a/src/librustc_trans/trans/cabi.rs b/src/librustc_trans/trans/cabi.rs
index 0214bf29eee..518b0ba73f8 100644
--- a/src/librustc_trans/trans/cabi.rs
+++ b/src/librustc_trans/trans/cabi.rs
@@ -65,8 +65,8 @@ impl ArgType {
         ArgType {
             kind: Indirect,
             ty: ty,
-            cast: option::None,
-            pad: option::None,
+            cast: option::Option::None,
+            pad: option::Option::None,
             attr: attr
         }
     }
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 176fe7096e7..746109ef113 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -49,8 +49,7 @@ use trans::monomorphize;
 use trans::type_::Type;
 use trans::type_of;
 use middle::ty::{mod, Ty};
-use middle::typeck::coherence::make_substs_for_receiver_types;
-use middle::typeck::MethodCall;
+use middle::ty::MethodCall;
 use util::ppaux::Repr;
 use util::ppaux::ty_to_string;
 
@@ -573,7 +572,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
 
                     // Compute the first substitution
                     let first_subst =
-                        make_substs_for_receiver_types(tcx, &*trait_ref, &*method)
+                        ty::make_substs_for_receiver_types(tcx, &*trait_ref, &*method)
                         .erase_regions();
 
                     // And compose them
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index febb33f6c54..a8256176c26 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -19,6 +19,7 @@ use llvm;
 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
 use llvm::{True, False, Bool};
 use middle::def;
+use middle::infer;
 use middle::lang_items::LangItem;
 use middle::mem_categorization as mc;
 use middle::region;
@@ -36,8 +37,6 @@ use middle::traits;
 use middle::ty::{mod, Ty};
 use middle::ty_fold;
 use middle::ty_fold::TypeFoldable;
-use middle::typeck;
-use middle::typeck::infer;
 use util::ppaux::Repr;
 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
 
@@ -273,11 +272,6 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
         }
     }
 
-    pub fn out_arg_pos(&self) -> uint {
-        assert!(self.caller_expects_out_pointer);
-        0u
-    }
-
     pub fn env_arg_pos(&self) -> uint {
         if self.caller_expects_out_pointer {
             1u
@@ -468,7 +462,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
         Ok(node_id_type(self, id))
     }
 
-    fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option<Ty<'tcx>> {
+    fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
         self.tcx()
             .method_map
             .borrow()
@@ -481,7 +475,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
     }
 
     fn is_method_call(&self, id: ast::NodeId) -> bool {
-        self.tcx().method_map.borrow().contains_key(&typeck::MethodCall::expr(id))
+        self.tcx().method_map.borrow().contains_key(&ty::MethodCall::expr(id))
     }
 
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
@@ -870,7 +864,7 @@ pub enum ExprOrMethodCall {
     ExprId(ast::NodeId),
 
     // Type parameters for a method call like `a.foo::<int>()`
-    MethodCall(typeck::MethodCall)
+    MethodCall(ty::MethodCall)
 }
 
 pub fn node_id_substs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 8220645cec7..fd9d6b8f2c3 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -347,10 +347,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
         &self.link_meta
     }
 
-    pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> {
-        &self.symbol_hasher
-    }
-
     pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
         &self.tcx
     }
diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs
index 3d32f6045a7..a1574aa2f0e 100644
--- a/src/librustc_trans/trans/controlflow.rs
+++ b/src/librustc_trans/trans/controlflow.rs
@@ -27,7 +27,7 @@ use trans::meth;
 use trans::type_::Type;
 use trans;
 use middle::ty;
-use middle::typeck::MethodCall;
+use middle::ty::MethodCall;
 use session::config::FullDebugInfo;
 use util::ppaux::Repr;
 use util::ppaux;
diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs
index f0fd94958ee..532ef690818 100644
--- a/src/librustc_trans/trans/datum.rs
+++ b/src/librustc_trans/trans/datum.rs
@@ -352,13 +352,6 @@ impl<'tcx> Datum<'tcx, Expr> {
             |_| bcx.sess().bug("assert_lvalue given rvalue"))
     }
 
-    /// Asserts that this datum *is* an lvalue and returns it.
-    pub fn assert_rvalue(self, bcx: Block) -> Datum<'tcx, Rvalue> {
-        self.match_kind(
-            |_| bcx.sess().bug("assert_rvalue given lvalue"),
-            |r| r)
-    }
-
     pub fn store_to_dest<'blk>(self,
                                bcx: Block<'blk, 'tcx>,
                                dest: expr::Dest,
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 646ee601a4c..d130dc0a55b 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -41,15 +41,23 @@ use middle::def;
 use middle::mem_categorization::Typer;
 use middle::subst::{mod, Subst};
 use trans::{_match, adt, asm, base, callee, closure, consts, controlflow};
-use trans::{debuginfo, glue, machine, meth, inline, tvec, type_of};
 use trans::base::*;
 use trans::build::*;
 use trans::cleanup::{mod, CleanupMethods};
 use trans::common::*;
 use trans::datum::*;
-use middle::ty::{mod, struct_fields, tup_fields};
-use middle::ty::{AdjustDerefRef, AdjustAddEnv, AutoUnsafe, AutoPtr, Ty};
-use middle::typeck::{mod, MethodCall};
+use trans::debuginfo;
+use trans::glue;
+use trans::machine;
+use trans::meth;
+use trans::inline;
+use trans::tvec;
+use trans::type_of;
+use middle::ty::{struct_fields, tup_fields};
+use middle::ty::{AdjustDerefRef, AdjustAddEnv, AutoUnsafe};
+use middle::ty::{AutoPtr};
+use middle::ty::{mod, Ty};
+use middle::ty::MethodCall;
 use util::common::indenter;
 use util::ppaux::Repr;
 use trans::machine::{llsize_of, llsize_of_alloc};
@@ -2091,7 +2099,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             // path (below) to dereference that `&T`.
             let datum = match method_call.adjustment {
                 // Always perform an AutoPtr when applying an overloaded auto-deref
-                typeck::AutoDeref(_) => unpack_datum!(bcx, auto_ref(bcx, datum, expr)),
+                ty::AutoDeref(_) => unpack_datum!(bcx, auto_ref(bcx, datum, expr)),
                 _ => datum
             };
 
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index ef431243b31..94ff526debd 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -31,8 +31,7 @@ use trans::machine;
 use trans::type_::Type;
 use trans::type_of::*;
 use middle::ty::{mod, Ty};
-use middle::typeck;
-use middle::typeck::MethodCall;
+use middle::ty::MethodCall;
 use util::ppaux::Repr;
 
 use std::c_str::ToCStr;
@@ -119,8 +118,8 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                  .unwrap();
 
     match origin {
-        typeck::MethodStatic(did) |
-        typeck::MethodStaticUnboxedClosure(did) => {
+        ty::MethodStatic(did) |
+        ty::MethodStaticUnboxedClosure(did) => {
             Callee {
                 bcx: bcx,
                 data: Fn(callee::trans_fn_ref(bcx,
@@ -129,7 +128,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
         }
 
-        typeck::MethodTypeParam(typeck::MethodParam {
+        ty::MethodTypeParam(ty::MethodParam {
             ref trait_ref,
             method_num
         }) => {
@@ -147,7 +146,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                        method_num, origin)
         }
 
-        typeck::MethodTraitObject(ref mt) => {
+        ty::MethodTraitObject(ref mt) => {
             let self_expr = match self_expr {
                 Some(self_expr) => self_expr,
                 None => {
diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs
index fe7697447ac..c00c477f4b8 100644
--- a/src/librustc_trans/trans/mod.rs
+++ b/src/librustc_trans/trans/mod.rs
@@ -8,40 +8,64 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub mod doc;
-pub mod macros;
-pub mod inline;
-pub mod monomorphize;
-pub mod controlflow;
-pub mod glue;
-pub mod datum;
-pub mod callee;
-pub mod expr;
-pub mod common;
-pub mod context;
-pub mod consts;
-pub mod type_of;
-pub mod build;
-pub mod builder;
-pub mod base;
-pub mod _match;
-pub mod closure;
-pub mod tvec;
-pub mod meth;
-pub mod cabi;
-pub mod cabi_x86;
-pub mod cabi_x86_64;
-pub mod cabi_x86_win64;
-pub mod cabi_arm;
-pub mod cabi_mips;
-pub mod foreign;
-pub mod intrinsic;
-pub mod debuginfo;
-pub mod machine;
-pub mod adt;
-pub mod asm;
-pub mod type_;
-pub mod value;
-pub mod basic_block;
-pub mod llrepr;
-pub mod cleanup;
+use llvm::{ContextRef, ModuleRef};
+use metadata::common::LinkMeta;
+use middle::dependency_format;
+
+pub use self::base::trans_crate;
+pub use self::context::CrateContext;
+pub use self::common::gensym_name;
+
+mod doc;
+mod macros;
+mod inline;
+mod monomorphize;
+mod controlflow;
+mod glue;
+mod datum;
+mod callee;
+mod expr;
+mod common;
+mod context;
+mod consts;
+mod type_of;
+mod build;
+mod builder;
+mod base;
+mod _match;
+mod closure;
+mod tvec;
+mod meth;
+mod cabi;
+mod cabi_x86;
+mod cabi_x86_64;
+mod cabi_x86_win64;
+mod cabi_arm;
+mod cabi_mips;
+mod foreign;
+mod intrinsic;
+mod debuginfo;
+mod machine;
+mod adt;
+mod asm;
+mod type_;
+mod value;
+mod basic_block;
+mod llrepr;
+mod cleanup;
+
+pub struct ModuleTranslation {
+    pub llcx: ContextRef,
+    pub llmod: ModuleRef,
+}
+
+pub struct CrateTranslation {
+    pub modules: Vec<ModuleTranslation>,
+    pub metadata_module: ModuleTranslation,
+    pub link: LinkMeta,
+    pub metadata: Vec<u8>,
+    pub reachable: Vec<String>,
+    pub crate_formats: dependency_format::Dependencies,
+    pub no_builtins: bool,
+}
+
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 89c004fc645..d95ad9a11c8 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -46,17 +46,17 @@
 //! Note that the self region for the `foo` defaulted to `&` in the first
 //! case but `&a` in the second.  Basically, defaults that appear inside
 //! an rptr (`&r.T`) use the region `r` that appears in the rptr.
+
+use middle::astconv_util::{ast_ty_to_prim_ty, check_path_args, NO_TPS, NO_REGIONS};
 use middle::const_eval;
 use middle::def;
 use middle::resolve_lifetime as rl;
 use middle::subst::{FnSpace, TypeSpace, AssocSpace, SelfSpace, Subst, Substs};
 use middle::subst::{VecPerParamSpace};
 use middle::ty::{mod, Ty};
-use middle::typeck::lookup_def_tcx;
-use middle::typeck::rscope::{UnelidableRscope, RegionScope, SpecificRscope,
-                             ShiftedRscope, BindingRscope};
-use middle::typeck::rscope;
-use middle::typeck::TypeAndSubsts;
+use rscope::{mod, UnelidableRscope, RegionScope, SpecificRscope,
+             ShiftedRscope, BindingRscope};
+use TypeAndSubsts;
 use util::common::ErrorReported;
 use util::nodemap::DefIdMap;
 use util::ppaux::{mod, Repr, UserString};
@@ -428,9 +428,9 @@ pub fn instantiate_trait_ref<'tcx,AC,RS>(this: &AC,
                                          where AC: AstConv<'tcx>,
                                                RS: RegionScope
 {
-    match lookup_def_tcx(this.tcx(),
-                         ast_trait_ref.path.span,
-                         ast_trait_ref.ref_id) {
+    match ::lookup_def_tcx(this.tcx(),
+                           ast_trait_ref.path.span,
+                           ast_trait_ref.ref_id) {
         def::DefTrait(trait_def_id) => {
             let trait_ref = Rc::new(ast_path_to_trait_ref(this, rscope, trait_def_id,
                                                           self_ty, &ast_trait_ref.path));
@@ -553,74 +553,6 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>(
     }
 }
 
-pub const NO_REGIONS: uint = 1;
-pub const NO_TPS: uint = 2;
-
-fn check_path_args(tcx: &ty::ctxt,
-                   path: &ast::Path,
-                   flags: uint) {
-    if (flags & NO_TPS) != 0u {
-        if path.segments.iter().any(|s| s.parameters.has_types()) {
-            span_err!(tcx.sess, path.span, E0109,
-                "type parameters are not allowed on this type");
-        }
-    }
-
-    if (flags & NO_REGIONS) != 0u {
-        if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
-            span_err!(tcx.sess, path.span, E0110,
-                "region parameters are not allowed on this type");
-        }
-    }
-}
-
-pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
-                               -> Option<Ty<'tcx>> {
-    match ast_ty.node {
-        ast::TyPath(ref path, id) => {
-            let a_def = match tcx.def_map.borrow().get(&id) {
-                None => {
-                    tcx.sess.span_bug(ast_ty.span,
-                                      format!("unbound path {}",
-                                              path.repr(tcx)).as_slice())
-                }
-                Some(&d) => d
-            };
-            match a_def {
-                def::DefPrimTy(nty) => {
-                    match nty {
-                        ast::TyBool => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_bool())
-                        }
-                        ast::TyChar => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_char())
-                        }
-                        ast::TyInt(it) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_int(it))
-                        }
-                        ast::TyUint(uit) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_uint(uit))
-                        }
-                        ast::TyFloat(ft) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_float(ft))
-                        }
-                        ast::TyStr => {
-                            Some(ty::mk_str(tcx))
-                        }
-                    }
-                }
-                _ => None
-            }
-        }
-        _ => None
-    }
-}
-
 /// Converts the given AST type to a built-in type. A "built-in type" is, at
 /// present, either a core numeric type, a string, or `Box`.
 pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
@@ -1544,7 +1476,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
     for &ast_bound in ast_bounds.iter() {
         match *ast_bound {
             ast::TraitTyParamBound(ref b) => {
-                match lookup_def_tcx(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
+                match ::lookup_def_tcx(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
                     def::DefTrait(trait_did) => {
                         match trait_def_ids.get(&trait_did) {
                             // Already seen this trait. We forbid
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index cdfd607d067..7dcf0aa3e21 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 use middle::def;
+use middle::infer::{mod, resolve};
 use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding, pat_is_const};
 use middle::subst::{Subst, Substs};
 use middle::ty::{mod, Ty};
-use middle::typeck::check::{check_expr, check_expr_has_type, demand, FnCtxt};
-use middle::typeck::check::{instantiate_path, structurally_resolved_type, valid_range_bounds};
-use middle::typeck::infer::{mod, resolve};
-use middle::typeck::require_same_types;
+use check::{check_expr, check_expr_has_type, demand, FnCtxt};
+use check::{instantiate_path, structurally_resolved_type, valid_range_bounds};
+use require_same_types;
 use util::nodemap::FnvHashMap;
 
 use std::cmp;
diff --git a/src/librustc/middle/typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 0a93b3a5ec7..34030ae4493 100644
--- a/src/librustc/middle/typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -14,11 +14,11 @@ use super::check_fn;
 use super::{Expectation, ExpectCastableToType, ExpectHasType, NoExpectation};
 use super::FnCtxt;
 
+use astconv;
+use middle::infer;
 use middle::subst;
 use middle::ty::{mod, Ty};
-use middle::typeck::astconv;
-use middle::typeck::infer;
-use middle::typeck::rscope::RegionScope;
+use rscope::RegionScope;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_util;
diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 1e45d059b84..9eb0e17b8e5 100644
--- a/src/librustc/middle/typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -9,14 +9,13 @@
 // except according to those terms.
 
 
+use check::FnCtxt;
 use middle::ty::{mod, Ty};
-use middle::typeck::check::FnCtxt;
-use middle::typeck::infer;
-use middle::typeck::infer::resolve_type;
-use middle::typeck::infer::resolve::try_resolve_tvar_shallow;
+use middle::infer;
+use middle::infer::resolve_type;
+use middle::infer::resolve::try_resolve_tvar_shallow;
 
-use std::result::{Err, Ok};
-use std::result;
+use std::result::Result::{Err, Ok};
 use syntax::ast;
 use syntax::codemap::Span;
 use util::ppaux::Repr;
@@ -29,12 +28,6 @@ pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
         |sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) })
 }
 
-pub fn subtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
-                         expected: Ty<'tcx>, actual: Ty<'tcx>) {
-    suptype_with_fn(fcx, sp, true, actual, expected,
-        |sp, a, e, s| { fcx.report_mismatched_types(sp, e, a, s) })
-}
-
 pub fn suptype_with_fn<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                  sp: Span,
                                  b_is_expected: bool,
@@ -44,8 +37,8 @@ pub fn suptype_with_fn<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // n.b.: order of actual, expected is reversed
     match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp),
                           ty_b, ty_a) {
-      result::Ok(()) => { /* ok */ }
-      result::Err(ref err) => {
+      Ok(()) => { /* ok */ }
+      Err(ref err) => {
           handle_err(sp, ty_a, ty_b, err);
       }
     }
@@ -75,8 +68,8 @@ pub fn coerce<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
                      try_resolve_tvar_shallow).unwrap_or(expected)
     } else { expected };
     match fcx.mk_assignty(expr, expr_ty, expected) {
-      result::Ok(()) => { /* ok */ }
-      result::Err(ref err) => {
+      Ok(()) => { /* ok */ }
+      Err(ref err) => {
         fcx.report_mismatched_types(sp, expected, expr_ty, err);
       }
     }
diff --git a/src/librustc/middle/typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index e866627be3d..1fe73f0478d 100644
--- a/src/librustc/middle/typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -10,13 +10,14 @@
 
 use super::probe;
 
+use check::{mod, FnCtxt, NoPreference, PreferMutLvalue};
 use middle::subst::{mod, Subst};
 use middle::traits;
 use middle::ty::{mod, Ty};
-use middle::typeck::check::{mod, FnCtxt, NoPreference, PreferMutLvalue};
-use middle::typeck::{MethodCall, MethodCallee, MethodObject, MethodOrigin,
-                     MethodParam, MethodStatic, MethodTraitObject, MethodTypeParam};
-use middle::typeck::infer::{mod, InferCtxt};
+use middle::ty::{MethodCall, MethodCallee, MethodObject, MethodOrigin,
+                 MethodParam, MethodStatic, MethodTraitObject, MethodTypeParam};
+use middle::infer;
+use middle::infer::InferCtxt;
 use middle::ty_fold::HigherRankedFoldable;
 use syntax::ast;
 use syntax::codemap::Span;
diff --git a/src/librustc/middle/typeck/check/method/doc.rs b/src/librustc_typeck/check/method/doc.rs
index 6129e38e39c..6129e38e39c 100644
--- a/src/librustc/middle/typeck/check/method/doc.rs
+++ b/src/librustc_typeck/check/method/doc.rs
diff --git a/src/librustc/middle/typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 34c3292f8cd..f87a4c9294b 100644
--- a/src/librustc/middle/typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -10,19 +10,17 @@
 
 //! Method lookup: the secret sauce of Rust. See `doc.rs`.
 
+use astconv::AstConv;
+use check::{FnCtxt};
+use check::{impl_self_ty};
+use check::vtable;
+use check::vtable::select_new_fcx_obligations;
 use middle::subst;
 use middle::subst::{Subst};
 use middle::traits;
 use middle::ty::*;
 use middle::ty;
-use middle::typeck::astconv::AstConv;
-use middle::typeck::check::{FnCtxt};
-use middle::typeck::check::{impl_self_ty};
-use middle::typeck::check::vtable;
-use middle::typeck::check::vtable::select_new_fcx_obligations;
-use middle::typeck::infer;
-use middle::typeck::{MethodCallee};
-use middle::typeck::{MethodParam, MethodTypeParam};
+use middle::infer;
 use util::ppaux::{Repr, UserString};
 
 use std::rc::Rc;
diff --git a/src/librustc/middle/typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 484d72130e6..6ff276edbce 100644
--- a/src/librustc/middle/typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -12,17 +12,17 @@ use super::{MethodError,Ambiguity,NoMatch};
 use super::MethodIndex;
 use super::{CandidateSource,ImplSource,TraitSource};
 
+use check;
+use check::{FnCtxt, NoPreference};
 use middle::fast_reject;
 use middle::subst;
 use middle::subst::Subst;
 use middle::traits;
 use middle::ty::{mod, Ty};
+use middle::ty::{MethodObject};
 use middle::ty_fold::HigherRankedFoldable;
-use middle::typeck::check;
-use middle::typeck::check::{FnCtxt, NoPreference};
-use middle::typeck::{MethodObject};
-use middle::typeck::infer;
-use middle::typeck::infer::InferCtxt;
+use middle::infer;
+use middle::infer::InferCtxt;
 use syntax::ast;
 use syntax::codemap::{Span, DUMMY_SP};
 use std::collections::HashSet;
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 641cbd11d64..cdf34c7f4d2 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -31,7 +31,7 @@ can be broken down into several distinct phases:
 
   In the process of checking, various constraints will be placed on
   these type variables through the subtyping relationships requested
-  through the `demand` module.  The `typeck::infer` module is in charge
+  through the `demand` module.  The `infer` module is in charge
   of resolving those constraints.
 
 - regionck: after main is complete, the regionck pass goes over all
@@ -82,8 +82,10 @@ pub use self::Expectation::*;
 use self::IsBinopAssignment::*;
 use self::TupleArgumentsFlag::*;
 
-use session::Session;
+use astconv::{mod, ast_region_to_region, ast_ty_to_ty, AstConv};
+use check::_match::pat_ctxt;
 use middle::{const_eval, def, traits};
+use middle::infer;
 use middle::lang_items::IteratorItem;
 use middle::mem_categorization::{mod, McResult};
 use middle::pat_util::{mod, pat_id_map};
@@ -93,12 +95,12 @@ use middle::ty::{FnSig, VariantInfo, Polytype};
 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
 use middle::ty::{mod, Ty};
 use middle::ty::liberate_late_bound_regions;
+use middle::ty::{MethodCall, MethodCallee, MethodMap, ObjectCastMap};
 use middle::ty_fold::TypeFolder;
-use middle::typeck::astconv::{mod, ast_region_to_region, ast_ty_to_ty, AstConv};
-use middle::typeck::check::_match::pat_ctxt;
-use middle::typeck::rscope::RegionScope;
-use middle::typeck::{mod, CrateCtxt, infer, lookup_def_ccx, no_params, require_same_types};
-use middle::typeck::{MethodCall, MethodCallee, MethodMap, ObjectCastMap, TypeAndSubsts};
+use rscope::RegionScope;
+use session::Session;
+use {CrateCtxt, lookup_def_ccx, no_params, require_same_types};
+use TypeAndSubsts;
 use middle::lang_items::TypeIdLangItem;
 use lint;
 use util::common::{block_query, indenter, loop_query};
@@ -279,7 +281,7 @@ impl<'a, 'tcx> mem_categorization::Typer<'tcx> for FnCtxt<'a, 'tcx> {
     fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
         Ok(self.node_ty(id))
     }
-    fn node_method_ty(&self, method_call: typeck::MethodCall)
+    fn node_method_ty(&self, method_call: ty::MethodCall)
                       -> Option<Ty<'tcx>> {
         self.inh.method_map.borrow().get(&method_call).map(|m| m.ty)
     }
@@ -287,7 +289,7 @@ impl<'a, 'tcx> mem_categorization::Typer<'tcx> for FnCtxt<'a, 'tcx> {
         &self.inh.adjustments
     }
     fn is_method_call(&self, id: ast::NodeId) -> bool {
-        self.inh.method_map.borrow().contains_key(&typeck::MethodCall::expr(id))
+        self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id))
     }
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
         self.tcx().temporary_scope(rvalue_id)
@@ -359,6 +361,17 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckItemTypesVisitor<'a, 'tcx> {
         check_item(self.ccx, i);
         visit::walk_item(self, i);
     }
+
+    fn visit_ty(&mut self, t: &ast::Ty) {
+        match t.node {
+            ast::TyFixedLengthVec(_, ref expr) => {
+                check_const_in_type(self.ccx, &**expr, ty::mk_uint());
+            }
+            _ => {}
+        }
+
+        visit::walk_ty(self, t);
+    }
 }
 
 pub fn check_item_types(ccx: &CrateCtxt) {
@@ -1734,8 +1747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.register_unsize_obligations(span, &**u)
             }
             ty::UnsizeVtable(ref ty_trait, self_ty) => {
-                vtable::check_object_safety(self.tcx(), ty_trait, span);
-
+                vtable::check_object_safety(self.tcx(), &ty_trait.principal, span);
                 // If the type is `Foo+'a`, ensures that the type
                 // being cast to `Foo+'a` implements `Foo`:
                 vtable::register_object_cast_obligations(self,
@@ -1860,13 +1872,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    /// Fetch type of `expr` after applying adjustments that have been recorded in the fcx.
-    pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
-        let adjustments = self.inh.adjustments.borrow();
-        let adjustment = adjustments.get(&expr.id);
-        self.adjust_expr_ty(expr, adjustment)
-    }
-
     /// Apply `adjustment` to the type of `expr`
     pub fn adjust_expr_ty(&self,
                           expr: &ast::Expr,
@@ -1919,16 +1924,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
     }
 
-    pub fn can_mk_subty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>)
-                        -> Result<(), ty::type_err<'tcx>> {
-        infer::can_mk_subty(self.infcx(), sub, sup)
-    }
-
-    pub fn can_mk_eqty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>)
-                       -> Result<(), ty::type_err<'tcx>> {
-        infer::can_mk_eqty(self.infcx(), sub, sup)
-    }
-
     pub fn mk_assignty(&self,
                        expr: &ast::Expr,
                        sub: Ty<'tcx>,
@@ -3260,7 +3255,7 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             Some(method) => {
                 let method_ty = method.ty;
                 // HACK(eddyb) Fully qualified path to work around a resolve bug.
-                let method_call = ::middle::typeck::MethodCall::expr(op_ex.id);
+                let method_call = ::middle::ty::MethodCall::expr(op_ex.id);
                 fcx.inh.method_map.borrow_mut().insert(method_call, method);
                 match check_method_argument_types(fcx,
                                             op_ex.span,
@@ -4670,25 +4665,18 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 /// Checks a constant appearing in a type. At the moment this is just the
 /// length expression in a fixed-length vector, but someday it might be
 /// extended to type-level numeric literals.
-pub fn check_const_in_type<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                 expr: &ast::Expr,
-                                 expected_type: Ty<'tcx>) {
-    // Synthesize a crate context. The trait map is not needed here (though I
-    // imagine it will be if we have associated statics --pcwalton), so we
-    // leave it blank.
-    let ccx = CrateCtxt {
-        trait_map: NodeMap::new(),
-        tcx: tcx,
-    };
-    let inh = static_inherited_fields(&ccx);
-    let fcx = blank_fn_ctxt(&ccx, &inh, ty::FnConverging(expected_type), expr.id);
+fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
+                                expr: &ast::Expr,
+                                expected_type: Ty<'tcx>) {
+    let inh = static_inherited_fields(ccx);
+    let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
     check_const_with_ty(&fcx, expr.span, expr, expected_type);
 }
 
-pub fn check_const(ccx: &CrateCtxt,
-                   sp: Span,
-                   e: &ast::Expr,
-                   id: ast::NodeId) {
+fn check_const(ccx: &CrateCtxt,
+               sp: Span,
+               e: &ast::Expr,
+               id: ast::NodeId) {
     let inh = static_inherited_fields(ccx);
     let rty = ty::node_id_to_type(ccx.tcx, id);
     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
@@ -4696,10 +4684,10 @@ pub fn check_const(ccx: &CrateCtxt,
     check_const_with_ty(&fcx, sp, e, declty);
 }
 
-pub fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                     _: Span,
-                                     e: &ast::Expr,
-                                     declty: Ty<'tcx>) {
+fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                 _: Span,
+                                 e: &ast::Expr,
+                                 declty: Ty<'tcx>) {
     // Gather locals in statics (because of block expressions).
     // This is technically unnecessary because locals in static items are forbidden,
     // but prevents type checking from blowing up before const checking can properly
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 08f7f9cf5e3..2aec4393de9 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -114,20 +114,19 @@
 //! then mean that all later passes would have to check for these figments
 //! and report an error, and it just seems like more mess in the end.)
 
+use astconv::AstConv;
+use check::FnCtxt;
+use check::regionmanip;
+use check::vtable;
 use middle::def;
 use middle::mem_categorization as mc;
 use middle::region::CodeExtent;
 use middle::traits;
 use middle::ty::{ReScope};
-use middle::ty::{mod, Ty};
-use middle::typeck::astconv::AstConv;
-use middle::typeck::check::FnCtxt;
-use middle::typeck::check::regionmanip;
-use middle::typeck::check::vtable;
-use middle::typeck::infer::resolve_and_force_all_but_regions;
-use middle::typeck::infer::resolve_type;
-use middle::typeck::infer;
-use middle::typeck::MethodCall;
+use middle::ty::{mod, Ty, MethodCall};
+use middle::infer::resolve_and_force_all_but_regions;
+use middle::infer::resolve_type;
+use middle::infer;
 use middle::pat_util;
 use util::nodemap::{DefIdMap, NodeMap, FnvHashMap};
 use util::ppaux::{ty_to_string, Repr};
diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc_typeck/check/regionmanip.rs
index 55214618aa9..92dfd8b5f56 100644
--- a/src/librustc/middle/typeck/check/regionmanip.rs
+++ b/src/librustc_typeck/check/regionmanip.rs
@@ -380,3 +380,22 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
         }
     }
 }
+
+impl<'tcx> Repr<'tcx> for WfConstraint<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt) -> String {
+        match *self {
+            RegionSubRegionConstraint(_, r_a, r_b) => {
+                format!("RegionSubRegionConstraint({}, {})",
+                        r_a.repr(tcx),
+                        r_b.repr(tcx))
+            }
+
+            RegionSubParamConstraint(_, r, p) => {
+                format!("RegionSubParamConstraint({}, {})",
+                        r.repr(tcx),
+                        p.repr(tcx))
+            }
+        }
+    }
+}
+
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs
index 84cb74b4de2..b9f7eb3f271 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc_typeck/check/vtable.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use check::{FnCtxt, structurally_resolved_type};
 use middle::subst::{SelfSpace, FnSpace};
 use middle::traits;
 use middle::traits::{SelectionError, OutputTypeParameterMismatch, Overflow, Unimplemented};
@@ -15,9 +16,7 @@ use middle::traits::{Obligation, obligation_for_builtin_bound};
 use middle::traits::{FulfillmentError, CodeSelectionError, CodeAmbiguity};
 use middle::traits::{ObligationCause};
 use middle::ty::{mod, Ty};
-use middle::typeck::check::{FnCtxt,
-                            structurally_resolved_type};
-use middle::typeck::infer;
+use middle::infer;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::Span;
@@ -46,7 +45,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
             // Ensure that if ~T is cast to ~Trait, then T : Trait
             push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
-            check_object_safety(fcx.tcx(), object_trait, source_expr.span);
+            check_object_safety(fcx.tcx(), &object_trait.principal, source_expr.span);
         }
 
         (&ty::ty_rptr(referent_region, ty::mt { ty: referent_ty,
@@ -70,7 +69,7 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                target_region,
                                referent_region);
 
-                check_object_safety(fcx.tcx(), object_trait, source_expr.span);
+                check_object_safety(fcx.tcx(), &object_trait.principal, source_expr.span);
             }
         }
 
@@ -134,17 +133,32 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 // self by value, has no type parameters and does not use the `Self` type, except
 // in self position.
 pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                 object_trait: &ty::TyTrait<'tcx>,
+                                 object_trait: &ty::TraitRef<'tcx>,
+                                 span: Span) {
+
+    let mut object = object_trait.clone();
+    if object.substs.types.len(SelfSpace) == 0 {
+        object.substs.types.push(SelfSpace, ty::mk_err());
+    }
+
+    let object = Rc::new(object);
+    for tr in traits::supertraits(tcx, object) {
+        check_object_safety_inner(tcx, &*tr, span);
+    }
+}
+
+fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                 object_trait: &ty::TraitRef<'tcx>,
                                  span: Span) {
     // Skip the fn_once lang item trait since only the compiler should call
     // `call_once` which is the method which takes self by value. What could go
     // wrong?
     match tcx.lang_items.fn_once_trait() {
-        Some(def_id) if def_id == object_trait.principal.def_id => return,
+        Some(def_id) if def_id == object_trait.def_id => return,
         _ => {}
     }
 
-    let trait_items = ty::trait_items(tcx, object_trait.principal.def_id);
+    let trait_items = ty::trait_items(tcx, object_trait.def_id);
 
     let mut errors = Vec::new();
     for item in trait_items.iter() {
@@ -158,7 +172,7 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
 
     let mut errors = errors.iter().flat_map(|x| x.iter()).peekable();
     if errors.peek().is_some() {
-        let trait_name = ty::item_path_str(tcx, object_trait.principal.def_id);
+        let trait_name = ty::item_path_str(tcx, object_trait.def_id);
         span_err!(tcx.sess, span, E0038,
             "cannot convert to a trait object because trait `{}` is not object-safe",
             trait_name);
diff --git a/src/librustc/middle/typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 8535ec4fa6e..1769c588ec1 100644
--- a/src/librustc/middle/typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use astconv::AstConv;
+use check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck};
+use CrateCtxt;
 use middle::region;
 use middle::subst;
 use middle::subst::{Subst};
@@ -15,9 +18,6 @@ use middle::traits;
 use middle::ty::{mod, Ty};
 use middle::ty::liberate_late_bound_regions;
 use middle::ty_fold::{TypeFolder, TypeFoldable};
-use middle::typeck::astconv::AstConv;
-use middle::typeck::check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck};
-use middle::typeck::CrateCtxt;
 use util::ppaux::Repr;
 
 use std::collections::HashSet;
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 23af30b44d9..777f354bec1 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -13,18 +13,17 @@
 // substitutions.
 use self::ResolveReason::*;
 
+use astconv::AstConv;
+use check::FnCtxt;
 use middle::def;
 use middle::pat_util;
-use middle::ty::{mod, Ty};
+use middle::ty::{mod, Ty, MethodCall, MethodCallee};
 use middle::ty_fold::{TypeFolder,TypeFoldable};
-use middle::typeck::astconv::AstConv;
-use middle::typeck::check::FnCtxt;
-use middle::typeck::infer::{force_all, resolve_all, resolve_region};
-use middle::typeck::infer::resolve_type;
-use middle::typeck::infer;
-use middle::typeck::{MethodCall, MethodCallee};
-use middle::typeck::write_substs_to_tcx;
-use middle::typeck::write_ty_to_tcx;
+use middle::infer::{force_all, resolve_all, resolve_region};
+use middle::infer::resolve_type;
+use middle::infer;
+use write_substs_to_tcx;
+use write_ty_to_tcx;
 use util::ppaux::Repr;
 
 use std::cell::Cell;
diff --git a/src/librustc/middle/typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 758608b79c2..b8642ddde40 100644
--- a/src/librustc/middle/typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -19,7 +19,6 @@
 use metadata::csearch::{each_impl, get_impl_trait};
 use metadata::csearch;
 use middle::subst;
-use middle::subst::{Substs};
 use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
 use middle::ty::{TypeTraitItemId, lookup_item_type};
 use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
@@ -31,10 +30,10 @@ use middle::ty::{ty_closure};
 use middle::ty::type_is_ty_var;
 use middle::subst::Subst;
 use middle::ty;
-use middle::typeck::CrateCtxt;
-use middle::typeck::infer::combine::Combine;
-use middle::typeck::infer::InferCtxt;
-use middle::typeck::infer::{new_infer_ctxt, resolve_ivar, resolve_type};
+use CrateCtxt;
+use middle::infer::combine::Combine;
+use middle::infer::InferCtxt;
+use middle::infer::{new_infer_ctxt, resolve_ivar, resolve_type};
 use std::collections::{HashSet};
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -477,27 +476,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
     }
 }
 
-/// Substitutes the values for the receiver's type parameters that are found in method, leaving the
-/// method's type parameters intact.
-pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                            trait_ref: &ty::TraitRef<'tcx>,
-                                            method: &ty::Method<'tcx>)
-                                            -> subst::Substs<'tcx>
-{
-    let meth_tps: Vec<Ty> =
-        method.generics.types.get_slice(subst::FnSpace)
-              .iter()
-              .map(|def| ty::mk_param_from_def(tcx, def))
-              .collect();
-    let meth_regions: Vec<ty::Region> =
-        method.generics.regions.get_slice(subst::FnSpace)
-              .iter()
-              .map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
-                                          def.index, def.name))
-              .collect();
-    trait_ref.substs.clone().with_method(meth_tps, meth_regions)
-}
-
 fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
                                            impl_id: ast::DefId,
                                            impl_poly_type: &ty::Polytype<'tcx>,
@@ -507,7 +485,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
                                            provided_source: Option<ast::DefId>)
                                            -> ty::Method<'tcx>
 {
-    let combined_substs = make_substs_for_receiver_types(tcx, trait_ref, method);
+    let combined_substs = ty::make_substs_for_receiver_types(tcx, trait_ref, method);
 
     debug!("subst_receiver_types_in_method_ty: combined_substs={}",
            combined_substs.repr(tcx));
diff --git a/src/librustc/middle/typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index dc3afaae35f..dc3afaae35f 100644
--- a/src/librustc/middle/typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
diff --git a/src/librustc/middle/typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index 9f10a58f458..0e74d4578d9 100644
--- a/src/librustc/middle/typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -13,8 +13,7 @@
 
 use middle::traits;
 use middle::ty;
-use middle::typeck::infer::{new_infer_ctxt};
-use middle::typeck::infer;
+use middle::infer::{mod, new_infer_ctxt};
 use syntax::ast::{DefId};
 use syntax::ast::{LOCAL_CRATE};
 use syntax::ast;
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc_typeck/collect.rs
index 6e989dd73db..717e886029a 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -32,6 +32,9 @@ as `ty_param()` instances.
 use self::ConvertMethodContext::*;
 use self::CreateTypeParametersForAssociatedTypesFlag::*;
 
+use astconv::{AstConv, ty_of_arg};
+use astconv::{ast_ty_to_ty, ast_region_to_region};
+use astconv;
 use metadata::csearch;
 use middle::def;
 use middle::lang_items::SizedTraitLangItem;
@@ -43,13 +46,9 @@ use middle::ty::{ImplContainer, ImplOrTraitItemContainer, TraitContainer};
 use middle::ty::{Polytype};
 use middle::ty::{mod, Ty};
 use middle::ty_fold::TypeFolder;
-use middle::typeck::astconv::{AstConv, ty_of_arg};
-use middle::typeck::astconv::{ast_ty_to_ty, ast_region_to_region};
-use middle::typeck::astconv;
-use middle::typeck::infer;
-use middle::typeck::rscope::*;
-use middle::typeck::{CrateCtxt, lookup_def_tcx, no_params, write_ty_to_tcx};
-use middle::typeck;
+use middle::infer;
+use rscope::*;
+use {CrateCtxt, lookup_def_tcx, no_params, write_ty_to_tcx};
 use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux;
 use util::ppaux::{Repr,UserString};
@@ -2159,13 +2158,13 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
                base_type.repr(crate_context.tcx),
                base_type_free.repr(crate_context.tcx));
         let infcx = infer::new_infer_ctxt(crate_context.tcx);
-        drop(typeck::require_same_types(crate_context.tcx,
-                                        Some(&infcx),
-                                        false,
-                                        explicit_self.span,
-                                        base_type_free,
-                                        required_type_free,
-                                        || {
+        drop(::require_same_types(crate_context.tcx,
+                                  Some(&infcx),
+                                  false,
+                                  explicit_self.span,
+                                  base_type_free,
+                                  required_type_free,
+                                  || {
                 format!("mismatched self type: expected `{}`",
                         ppaux::ty_to_string(crate_context.tcx, required_type))
         }));
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
new file mode 100644
index 00000000000..36e81f18103
--- /dev/null
+++ b/src/librustc_typeck/diagnostics.rs
@@ -0,0 +1,151 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_snake_case)]
+
+register_diagnostic!(E0001, r##"
+    This error suggests that the expression arm corresponding to the noted pattern
+    will never be reached as for all possible values of the expression being matched,
+    one of the preceeding patterns will match.
+
+    This means that perhaps some of the preceeding patterns are too general, this
+    one is too specific or the ordering is incorrect.
+"##)
+
+register_diagnostics!(
+    E0002,
+    E0003,
+    E0004,
+    E0005,
+    E0006,
+    E0007,
+    E0008,
+    E0009,
+    E0010,
+    E0011,
+    E0012,
+    E0013,
+    E0014,
+    E0015,
+    E0016,
+    E0017,
+    E0018,
+    E0019,
+    E0020,
+    E0022,
+    E0023,
+    E0024,
+    E0025,
+    E0026,
+    E0027,
+    E0029,
+    E0030,
+    E0031,
+    E0033,
+    E0034,
+    E0035,
+    E0036,
+    E0038,
+    E0040,
+    E0044,
+    E0045,
+    E0046,
+    E0049,
+    E0050,
+    E0051,
+    E0052,
+    E0053,
+    E0054,
+    E0055,
+    E0056,
+    E0057,
+    E0059,
+    E0060,
+    E0061,
+    E0062,
+    E0063,
+    E0066,
+    E0067,
+    E0068,
+    E0069,
+    E0070,
+    E0071,
+    E0072,
+    E0073,
+    E0074,
+    E0075,
+    E0076,
+    E0077,
+    E0079,
+    E0080,
+    E0081,
+    E0082,
+    E0083,
+    E0084,
+    E0085,
+    E0086,
+    E0087,
+    E0088,
+    E0089,
+    E0090,
+    E0091,
+    E0092,
+    E0093,
+    E0094,
+    E0100,
+    E0101,
+    E0102,
+    E0103,
+    E0104,
+    E0106,
+    E0107,
+    E0108,
+    E0109,
+    E0110,
+    E0116,
+    E0117,
+    E0118,
+    E0119,
+    E0120,
+    E0121,
+    E0122,
+    E0124,
+    E0127,
+    E0128,
+    E0129,
+    E0130,
+    E0131,
+    E0132,
+    E0133,
+    E0134,
+    E0135,
+    E0136,
+    E0137,
+    E0138,
+    E0139,
+    E0140,
+    E0141,
+    E0152,
+    E0153,
+    E0157,
+    E0158,
+    E0159,
+    E0161,
+    E0162,
+    E0163,
+    E0164,
+    E0165,
+    E0166,
+    E0167,
+    E0168,
+    E0169,
+    E0171,
+    E0172
+)
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc_typeck/lib.rs
index 501dfcb2e2d..2f5b473567f 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc_typeck/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/*
+/*!
 
 typeck.rs, an introduction
 
@@ -57,16 +57,40 @@ independently:
   all subtyping and assignment constraints are met.  In essence, the check
   module specifies the constraints, and the infer module solves them.
 
+# Note
+
+This API is completely unstable and subject to change.
+
 */
 
+#![crate_name = "rustc_typeck"]
+#![experimental]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+      html_root_url = "http://doc.rust-lang.org/nightly/")]
+
+#![feature(default_type_params, globs, if_let, import_shadowing, macro_rules, phase, quote)]
+#![feature(slicing_syntax, tuple_indexing, unsafe_destructor)]
+#![feature(rustc_diagnostic_macros)]
 #![allow(non_camel_case_types)]
 
-pub use self::ExprAdjustment::*;
-pub use self::vtable_origin::*;
-pub use self::MethodOrigin::*;
+#[phase(plugin, link)] extern crate log;
+#[phase(plugin, link)] extern crate syntax;
+
+extern crate arena;
+extern crate rustc;
+
+pub use rustc::lint;
+pub use rustc::metadata;
+pub use rustc::middle;
+pub use rustc::session;
+pub use rustc::util;
 
 use middle::def;
 use middle::resolve;
+use middle::infer;
 use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::{mod, Ty};
@@ -74,222 +98,40 @@ use session::config;
 use util::common::time;
 use util::ppaux::Repr;
 use util::ppaux;
-use util::nodemap::{NodeMap, FnvHashMap};
 
-use std::cell::RefCell;
-use std::rc::Rc;
 use syntax::codemap::Span;
 use syntax::print::pprust::*;
 use syntax::{ast, ast_map, abi};
 
-pub mod check;
-pub mod rscope;
-pub mod astconv;
-pub mod infer;
-pub mod collect;
-pub mod coherence;
-pub mod variance;
-
-#[deriving(Clone, Encodable, Decodable, PartialEq, PartialOrd, Show)]
-pub struct param_index {
-    pub space: subst::ParamSpace,
-    pub index: uint
-}
-
-#[deriving(Clone, Show)]
-pub enum MethodOrigin<'tcx> {
-    // fully statically resolved method
-    MethodStatic(ast::DefId),
-
-    // fully statically resolved unboxed closure invocation
-    MethodStaticUnboxedClosure(ast::DefId),
+#[cfg(stage0)]
+mod diagnostics;
 
-    // method invoked on a type parameter with a bounded trait
-    MethodTypeParam(MethodParam<'tcx>),
-
-    // method invoked on a trait instance
-    MethodTraitObject(MethodObject<'tcx>),
-
-}
-
-// details for a method invoked with a receiver whose type is a type parameter
-// with a bounded trait.
-#[deriving(Clone, Show)]
-pub struct MethodParam<'tcx> {
-    // the precise trait reference that occurs as a bound -- this may
-    // be a supertrait of what the user actually typed.
-    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
-
-    // index of uint in the list of methods for the trait
-    pub method_num: uint,
-}
-
-// details for a method invoked with a receiver whose type is an object
-#[deriving(Clone, Show)]
-pub struct MethodObject<'tcx> {
-    // the (super)trait containing the method to be invoked
-    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
-
-    // the actual base trait id of the object
-    pub object_trait_id: ast::DefId,
-
-    // index of the method to be invoked amongst the trait's methods
-    pub method_num: uint,
-
-    // index into the actual runtime vtable.
-    // the vtable is formed by concatenating together the method lists of
-    // the base object trait and all supertraits;  this is the index into
-    // that vtable
-    pub real_index: uint,
-}
-
-#[deriving(Clone)]
-pub struct MethodCallee<'tcx> {
-    pub origin: MethodOrigin<'tcx>,
-    pub ty: Ty<'tcx>,
-    pub substs: subst::Substs<'tcx>
-}
-
-/// With method calls, we store some extra information in
-/// side tables (i.e method_map). We use
-/// MethodCall as a key to index into these tables instead of
-/// just directly using the expression's NodeId. The reason
-/// for this being that we may apply adjustments (coercions)
-/// with the resulting expression also needing to use the
-/// side tables. The problem with this is that we don't
-/// assign a separate NodeId to this new expression
-/// and so it would clash with the base expression if both
-/// needed to add to the side tables. Thus to disambiguate
-/// we also keep track of whether there's an adjustment in
-/// our key.
-#[deriving(Clone, PartialEq, Eq, Hash, Show)]
-pub struct MethodCall {
-    pub expr_id: ast::NodeId,
-    pub adjustment: ExprAdjustment
-}
-
-#[deriving(Clone, PartialEq, Eq, Hash, Show, Encodable, Decodable)]
-pub enum ExprAdjustment {
-    NoAdjustment,
-    AutoDeref(uint),
-    AutoObject
-}
+mod check;
+mod rscope;
+mod astconv;
+mod collect;
+mod coherence;
+mod variance;
 
-pub struct TypeAndSubsts<'tcx> {
+struct TypeAndSubsts<'tcx> {
     pub substs: subst::Substs<'tcx>,
     pub ty: Ty<'tcx>,
 }
 
-impl MethodCall {
-    pub fn expr(id: ast::NodeId) -> MethodCall {
-        MethodCall {
-            expr_id: id,
-            adjustment: NoAdjustment
-        }
-    }
-
-    pub fn autoobject(id: ast::NodeId) -> MethodCall {
-        MethodCall {
-            expr_id: id,
-            adjustment: AutoObject
-        }
-    }
-
-    pub fn autoderef(expr_id: ast::NodeId, autoderef: uint) -> MethodCall {
-        MethodCall {
-            expr_id: expr_id,
-            adjustment: AutoDeref(1 + autoderef)
-        }
-    }
-}
-
-// maps from an expression id that corresponds to a method call to the details
-// of the method to be invoked
-pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
-
-pub type vtable_param_res<'tcx> = Vec<vtable_origin<'tcx>>;
-
-// Resolutions for bounds of all parameters, left to right, for a given path.
-pub type vtable_res<'tcx> = VecPerParamSpace<vtable_param_res<'tcx>>;
-
-#[deriving(Clone)]
-pub enum vtable_origin<'tcx> {
-    /*
-      Statically known vtable. def_id gives the impl item
-      from whence comes the vtable, and tys are the type substs.
-      vtable_res is the vtable itself.
-     */
-    vtable_static(ast::DefId, subst::Substs<'tcx>, vtable_res<'tcx>),
-
-    /*
-      Dynamic vtable, comes from a parameter that has a bound on it:
-      fn foo<T:quux,baz,bar>(a: T) -- a's vtable would have a
-      vtable_param origin
-
-      The first argument is the param index (identifying T in the example),
-      and the second is the bound number (identifying baz)
-     */
-    vtable_param(param_index, uint),
-
-    /*
-      Vtable automatically generated for an unboxed closure. The def ID is the
-      ID of the closure expression.
-     */
-    vtable_unboxed_closure(ast::DefId),
-
-    /*
-      Asked to determine the vtable for ty_err. This is the value used
-      for the vtables of `Self` in a virtual call like `foo.bar()`
-      where `foo` is of object type. The same value is also used when
-      type errors occur.
-     */
-    vtable_error,
-}
-
-impl<'tcx> Repr<'tcx> for vtable_origin<'tcx> {
-    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
-        match *self {
-            vtable_static(def_id, ref tys, ref vtable_res) => {
-                format!("vtable_static({}:{}, {}, {})",
-                        def_id,
-                        ty::item_path_str(tcx, def_id),
-                        tys.repr(tcx),
-                        vtable_res.repr(tcx))
-            }
-
-            vtable_param(x, y) => {
-                format!("vtable_param({}, {})", x, y)
-            }
-
-            vtable_unboxed_closure(def_id) => {
-                format!("vtable_unboxed_closure({})", def_id)
-            }
-
-            vtable_error => {
-                format!("vtable_error")
-            }
-        }
-    }
-}
-
-// For every explicit cast into an object type, maps from the cast
-// expr to the associated trait ref.
-pub type ObjectCastMap<'tcx> = RefCell<NodeMap<Rc<ty::TraitRef<'tcx>>>>;
-
-pub struct CrateCtxt<'a, 'tcx: 'a> {
+struct CrateCtxt<'a, 'tcx: 'a> {
     // A mapping from method call sites to traits that have that method.
     trait_map: resolve::TraitMap,
     tcx: &'a ty::ctxt<'tcx>
 }
 
 // Functions that write types into the node type table
-pub fn write_ty_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
+fn write_ty_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
     debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_string(tcx, ty));
     assert!(!ty::type_needs_infer(ty));
     tcx.node_types.borrow_mut().insert(node_id, ty);
 }
 
-pub fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
+fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
                                  node_id: ast::NodeId,
                                  item_substs: ty::ItemSubsts<'tcx>) {
     if !item_substs.is_noop() {
@@ -302,7 +144,7 @@ pub fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
         tcx.item_substs.borrow_mut().insert(node_id, item_substs);
     }
 }
-pub fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
+fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
     match tcx.def_map.borrow().get(&id) {
         Some(x) => x.clone(),
         _ => {
@@ -311,12 +153,12 @@ pub fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
     }
 }
 
-pub fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
+fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
                    -> def::Def {
     lookup_def_tcx(ccx.tcx, sp, id)
 }
 
-pub fn no_params<'tcx>(t: Ty<'tcx>) -> ty::Polytype<'tcx> {
+fn no_params<'tcx>(t: Ty<'tcx>) -> ty::Polytype<'tcx> {
     ty::Polytype {
         generics: ty::Generics {types: VecPerParamSpace::empty(),
                                 regions: VecPerParamSpace::empty()},
@@ -324,7 +166,7 @@ pub fn no_params<'tcx>(t: Ty<'tcx>) -> ty::Polytype<'tcx> {
     }
 }
 
-pub fn require_same_types<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
+fn require_same_types<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
                                     maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
                                     t1_is_expected: bool,
                                     span: Span,
diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc_typeck/rscope.rs
index 3bca24f479f..3bca24f479f 100644
--- a/src/librustc/middle/typeck/rscope.rs
+++ b/src/librustc_typeck/rscope.rs
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc_typeck/variance.rs
index ade3144ce41..ade3144ce41 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6f1ddaff360..7e02891160a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -39,7 +39,6 @@ use syntax::parse::token;
 use syntax::ptr::P;
 
 use rustc_trans::back::link;
-use rustc_trans::driver::driver;
 use rustc::metadata::cstore;
 use rustc::metadata::csearch;
 use rustc::metadata::decoder;
@@ -48,6 +47,7 @@ use rustc::middle::subst;
 use rustc::middle::subst::VecPerParamSpace;
 use rustc::middle::ty;
 use rustc::middle::stability;
+use rustc::session::config;
 
 use std::rc::Rc;
 use std::u32;
@@ -131,7 +131,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
         externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
 
         // Figure out the name of this crate
-        let input = driver::FileInput(cx.src.clone());
+        let input = config::Input::File(cx.src.clone());
         let name = link::find_crate_name(None, self.attrs.as_slice(), &input);
 
         // Clean the crate, translating the entire libsyntax AST to one that is
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index b040a4bfd2a..4cd88bca51e 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 pub use self::MaybeTyped::*;
 
-use rustc_trans::driver::driver;
+use rustc_driver::driver;
 use rustc::session::{mod, config};
 use rustc::middle::{privacy, ty};
 use rustc::lint;
@@ -83,7 +83,7 @@ pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, externs: Externs,
 
     // Parse, resolve, and typecheck the given crate.
 
-    let input = driver::FileInput(cpath.clone());
+    let input = config::Input::File(cpath.clone());
 
     let warning_lint = lint::builtin::WARNINGS.name_lower();
 
@@ -122,7 +122,7 @@ pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, externs: Externs,
     let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
 
     let type_arena = TypedArena::new();
-    let driver::CrateAnalysis {
+    let ty::CrateAnalysis {
         exported_items, public_items, ty_cx, ..
     } = driver::phase_3_run_analysis_passes(sess, ast_map, &type_arena, name);
 
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 6e0b76d441b..9861d18ce51 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -23,7 +23,6 @@ use syntax::ast_util;
 
 use clean;
 use stability_summary::ModuleSummary;
-use html::item_type;
 use html::item_type::ItemType;
 use html::render;
 use html::render::{cache, CURRENT_LOCATION_KEY};
@@ -283,7 +282,7 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
                 url.push_str("/");
             }
             match shortty {
-                item_type::Module => {
+                ItemType::Module => {
                     url.push_str(fqp.last().unwrap().as_slice());
                     url.push_str("/index.html");
                 }
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index cb3ad9d063f..0ad12b957ba 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 //! Item types.
-pub use self::ItemType::*;
 
 use std::fmt;
 use clean;
@@ -35,8 +34,7 @@ pub enum ItemType {
     Method          = 10,
     StructField     = 11,
     Variant         = 12,
-    ForeignFunction = 13,
-    ForeignStatic   = 14,
+    // we used to have ForeignFunction and ForeignStatic. they are retired now.
     Macro           = 15,
     Primitive       = 16,
     AssociatedType  = 17,
@@ -44,27 +42,62 @@ pub enum ItemType {
 }
 
 impl ItemType {
+    pub fn from_item(item: &clean::Item) -> ItemType {
+        match item.inner {
+            clean::ModuleItem(..)          => ItemType::Module,
+            clean::StructItem(..)          => ItemType::Struct,
+            clean::EnumItem(..)            => ItemType::Enum,
+            clean::FunctionItem(..)        => ItemType::Function,
+            clean::TypedefItem(..)         => ItemType::Typedef,
+            clean::StaticItem(..)          => ItemType::Static,
+            clean::ConstantItem(..)        => ItemType::Constant,
+            clean::TraitItem(..)           => ItemType::Trait,
+            clean::ImplItem(..)            => ItemType::Impl,
+            clean::ViewItemItem(..)        => ItemType::ViewItem,
+            clean::TyMethodItem(..)        => ItemType::TyMethod,
+            clean::MethodItem(..)          => ItemType::Method,
+            clean::StructFieldItem(..)     => ItemType::StructField,
+            clean::VariantItem(..)         => ItemType::Variant,
+            clean::ForeignFunctionItem(..) => ItemType::Function, // no ForeignFunction
+            clean::ForeignStaticItem(..)   => ItemType::Static, // no ForeignStatic
+            clean::MacroItem(..)           => ItemType::Macro,
+            clean::PrimitiveItem(..)       => ItemType::Primitive,
+            clean::AssociatedTypeItem(..)  => ItemType::AssociatedType,
+        }
+    }
+
+    pub fn from_type_kind(kind: clean::TypeKind) -> ItemType {
+        match kind {
+            clean::TypeStruct   => ItemType::Struct,
+            clean::TypeEnum     => ItemType::Enum,
+            clean::TypeFunction => ItemType::Function,
+            clean::TypeTrait    => ItemType::Trait,
+            clean::TypeModule   => ItemType::Module,
+            clean::TypeStatic   => ItemType::Static,
+            clean::TypeVariant  => ItemType::Variant,
+            clean::TypeTypedef  => ItemType::Typedef,
+        }
+    }
+
     pub fn to_static_str(&self) -> &'static str {
         match *self {
-            Module          => "mod",
-            Struct          => "struct",
-            Enum            => "enum",
-            Function        => "fn",
-            Typedef         => "type",
-            Static          => "static",
-            Trait           => "trait",
-            Impl            => "impl",
-            ViewItem        => "viewitem",
-            TyMethod        => "tymethod",
-            Method          => "method",
-            StructField     => "structfield",
-            Variant         => "variant",
-            ForeignFunction => "ffi",
-            ForeignStatic   => "ffs",
-            Macro           => "macro",
-            Primitive       => "primitive",
-            AssociatedType  => "associatedtype",
-            Constant        => "constant",
+            ItemType::Module          => "mod",
+            ItemType::Struct          => "struct",
+            ItemType::Enum            => "enum",
+            ItemType::Function        => "fn",
+            ItemType::Typedef         => "type",
+            ItemType::Static          => "static",
+            ItemType::Trait           => "trait",
+            ItemType::Impl            => "impl",
+            ItemType::ViewItem        => "viewitem",
+            ItemType::TyMethod        => "tymethod",
+            ItemType::Method          => "method",
+            ItemType::StructField     => "structfield",
+            ItemType::Variant         => "variant",
+            ItemType::Macro           => "macro",
+            ItemType::Primitive       => "primitive",
+            ItemType::AssociatedType  => "associatedtype",
+            ItemType::Constant        => "constant",
         }
     }
 }
@@ -75,27 +108,3 @@ impl fmt::Show for ItemType {
     }
 }
 
-pub fn shortty(item: &clean::Item) -> ItemType {
-    match item.inner {
-        clean::ModuleItem(..)          => Module,
-        clean::StructItem(..)          => Struct,
-        clean::EnumItem(..)            => Enum,
-        clean::FunctionItem(..)        => Function,
-        clean::TypedefItem(..)         => Typedef,
-        clean::StaticItem(..)          => Static,
-        clean::ConstantItem(..)        => Constant,
-        clean::TraitItem(..)           => Trait,
-        clean::ImplItem(..)            => Impl,
-        clean::ViewItemItem(..)        => ViewItem,
-        clean::TyMethodItem(..)        => TyMethod,
-        clean::MethodItem(..)          => Method,
-        clean::StructFieldItem(..)     => StructField,
-        clean::VariantItem(..)         => Variant,
-        clean::ForeignFunctionItem(..) => ForeignFunction,
-        clean::ForeignStaticItem(..)   => ForeignStatic,
-        clean::MacroItem(..)           => Macro,
-        clean::PrimitiveItem(..)       => Primitive,
-        clean::AssociatedTypeItem(..)  => AssociatedType,
-    }
-}
-
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 896d070c155..23f31580619 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -160,6 +160,7 @@ r##"<!DOCTYPE html>
 }
 
 pub fn redirect(dst: &mut io::Writer, url: &str) -> io::IoResult<()> {
+    // <script> triggers a redirect before refresh, so this is fine.
     write!(dst,
 r##"<!DOCTYPE html>
 <html lang="en">
@@ -167,6 +168,8 @@ r##"<!DOCTYPE html>
     <meta http-equiv="refresh" content="0;URL={url}">
 </head>
 <body>
+    <p>Redirecting to <a href="{url}">{url}</a>...</p>
+    <script>location.replace("{url}" + location.search + location.hash);</script>
 </body>
 </html>"##,
     url = url,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 2be703e2458..9eee8e04f0c 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -61,8 +61,7 @@ use fold::DocFolder;
 use html::format::{VisSpace, Method, FnStyleSpace, MutableSpace, Stability};
 use html::format::{ConciseStability, TyParamBounds, WhereClause};
 use html::highlight;
-use html::item_type::{ItemType, shortty};
-use html::item_type;
+use html::item_type::ItemType;
 use html::layout;
 use html::markdown::Markdown;
 use html::markdown;
@@ -314,19 +313,8 @@ pub fn run(mut krate: clean::Crate,
     let paths: HashMap<ast::DefId, (Vec<String>, ItemType)> =
       analysis.as_ref().map(|a| {
         let paths = a.external_paths.borrow_mut().take().unwrap();
-        paths.into_iter().map(|(k, (v, t))| {
-            (k, (v, match t {
-                clean::TypeStruct => item_type::Struct,
-                clean::TypeEnum => item_type::Enum,
-                clean::TypeFunction => item_type::Function,
-                clean::TypeTrait => item_type::Trait,
-                clean::TypeModule => item_type::Module,
-                clean::TypeStatic => item_type::Static,
-                clean::TypeVariant => item_type::Variant,
-                clean::TypeTypedef => item_type::Typedef,
-            }))
-        }).collect()
-    }).unwrap_or(HashMap::new());
+        paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from_type_kind(t)))).collect()
+      }).unwrap_or(HashMap::new());
     let mut cache = Cache {
         impls: HashMap::new(),
         external_paths: paths.iter().map(|(&k, v)| (k, v.ref0().clone()))
@@ -359,7 +347,7 @@ pub fn run(mut krate: clean::Crate,
     for &(n, ref e) in krate.externs.iter() {
         cache.extern_locations.insert(n, extern_location(e, &cx.dst));
         let did = ast::DefId { krate: n, node: ast::CRATE_NODE_ID };
-        cache.paths.insert(did, (vec![e.name.to_string()], item_type::Module));
+        cache.paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
     }
 
     // Cache where all known primitives have their documentation located.
@@ -642,6 +630,11 @@ fn mkdir(path: &Path) -> io::IoResult<()> {
     }
 }
 
+/// Returns a documentation-level item type from the item.
+fn shortty(item: &clean::Item) -> ItemType {
+    ItemType::from_item(item)
+}
+
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
 /// things like ".." to components which preserve the "top down" hierarchy of a
 /// static HTML tree.
@@ -855,13 +848,13 @@ impl DocFolder for Cache {
                         let last = self.parent_stack.last().unwrap();
                         let did = *last;
                         let path = match self.paths.get(&did) {
-                            Some(&(_, item_type::Trait)) =>
+                            Some(&(_, ItemType::Trait)) =>
                                 Some(self.stack[..self.stack.len() - 1]),
                             // The current stack not necessarily has correlation for
                             // where the type was defined. On the other hand,
                             // `paths` always has the right information if present.
-                            Some(&(ref fqp, item_type::Struct)) |
-                            Some(&(ref fqp, item_type::Enum)) =>
+                            Some(&(ref fqp, ItemType::Struct)) |
+                            Some(&(ref fqp, ItemType::Enum)) =>
                                 Some(fqp[..fqp.len() - 1]),
                             Some(..) => Some(self.stack.as_slice()),
                             None => None
@@ -929,7 +922,7 @@ impl DocFolder for Cache {
             clean::VariantItem(..) if !self.privmod => {
                 let mut stack = self.stack.clone();
                 stack.pop();
-                self.paths.insert(item.def_id, (stack, item_type::Enum));
+                self.paths.insert(item.def_id, (stack, ItemType::Enum));
             }
 
             clean::PrimitiveItem(..) if item.visibility.is_some() => {
@@ -1251,6 +1244,10 @@ impl Context {
         for item in m.items.iter() {
             if self.ignore_private_item(item) { continue }
 
+            // avoid putting foreign items to the sidebar.
+            if let &clean::ForeignFunctionItem(..) = &item.inner { continue }
+            if let &clean::ForeignStaticItem(..) = &item.inner { continue }
+
             let short = shortty(item).to_static_str();
             let myname = match item.name {
                 None => continue,
@@ -1435,7 +1432,8 @@ impl<'a> fmt::Show for Item<'a> {
             clean::TypedefItem(ref t) => item_typedef(fmt, self.item, t),
             clean::MacroItem(ref m) => item_macro(fmt, self.item, m),
             clean::PrimitiveItem(ref p) => item_primitive(fmt, self.item, p),
-            clean::StaticItem(ref i) => item_static(fmt, self.item, i),
+            clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) =>
+                item_static(fmt, self.item, i),
             clean::ConstantItem(ref c) => item_constant(fmt, self.item, c),
             _ => Ok(())
         }
@@ -1490,45 +1488,48 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
         !cx.ignore_private_item(&items[*i])
     }).collect::<Vec<uint>>();
 
+    // the order of item types in the listing
+    fn reorder(ty: ItemType) -> u8 {
+        match ty {
+            ItemType::ViewItem        => 0,
+            ItemType::Primitive       => 1,
+            ItemType::Module          => 2,
+            ItemType::Macro           => 3,
+            ItemType::Struct          => 4,
+            ItemType::Enum            => 5,
+            ItemType::Constant        => 6,
+            ItemType::Static          => 7,
+            ItemType::Trait           => 8,
+            ItemType::Function        => 9,
+            ItemType::Typedef         => 10,
+            _                         => 11 + ty as u8,
+        }
+    }
+
     fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering {
-        if shortty(i1) == shortty(i2) {
+        let ty1 = shortty(i1);
+        let ty2 = shortty(i2);
+        if ty1 == ty2 {
             return i1.name.cmp(&i2.name);
         }
-        match (&i1.inner, &i2.inner) {
-            (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
-                match (&a.inner, &b.inner) {
-                    (&clean::ExternCrate(..), _) => Less,
-                    (_, &clean::ExternCrate(..)) => Greater,
-                    _ => idx1.cmp(&idx2),
+
+        let tycmp = reorder(ty1).cmp(&reorder(ty2));
+        if let Equal = tycmp {
+            // for reexports, `extern crate` takes precedence.
+            match (&i1.inner, &i2.inner) {
+                (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
+                    match (&a.inner, &b.inner) {
+                        (&clean::ExternCrate(..), _) => return Less,
+                        (_, &clean::ExternCrate(..)) => return Greater,
+                        _ => {}
+                    }
                 }
+                (_, _) => {}
             }
-            (&clean::ViewItemItem(..), _) => Less,
-            (_, &clean::ViewItemItem(..)) => Greater,
-            (&clean::PrimitiveItem(..), _) => Less,
-            (_, &clean::PrimitiveItem(..)) => Greater,
-            (&clean::ModuleItem(..), _) => Less,
-            (_, &clean::ModuleItem(..)) => Greater,
-            (&clean::MacroItem(..), _) => Less,
-            (_, &clean::MacroItem(..)) => Greater,
-            (&clean::StructItem(..), _) => Less,
-            (_, &clean::StructItem(..)) => Greater,
-            (&clean::EnumItem(..), _) => Less,
-            (_, &clean::EnumItem(..)) => Greater,
-            (&clean::ConstantItem(..), _) => Less,
-            (_, &clean::ConstantItem(..)) => Greater,
-            (&clean::StaticItem(..), _) => Less,
-            (_, &clean::StaticItem(..)) => Greater,
-            (&clean::ForeignFunctionItem(..), _) => Less,
-            (_, &clean::ForeignFunctionItem(..)) => Greater,
-            (&clean::ForeignStaticItem(..), _) => Less,
-            (_, &clean::ForeignStaticItem(..)) => Greater,
-            (&clean::TraitItem(..), _) => Less,
-            (_, &clean::TraitItem(..)) => Greater,
-            (&clean::FunctionItem(..), _) => Less,
-            (_, &clean::FunctionItem(..)) => Greater,
-            (&clean::TypedefItem(..), _) => Less,
-            (_, &clean::TypedefItem(..)) => Greater,
-            _ => idx1.cmp(&idx2),
+
+            idx1.cmp(&idx2)
+        } else {
+            tycmp
         }
     }
 
@@ -1545,26 +1546,24 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
                 try!(write!(w, "</table>"));
             }
             curty = myty;
-            let (short, name) = match myitem.inner {
-                clean::ModuleItem(..)          => ("modules", "Modules"),
-                clean::StructItem(..)          => ("structs", "Structs"),
-                clean::EnumItem(..)            => ("enums", "Enums"),
-                clean::FunctionItem(..)        => ("functions", "Functions"),
-                clean::TypedefItem(..)         => ("types", "Type Definitions"),
-                clean::StaticItem(..)          => ("statics", "Statics"),
-                clean::ConstantItem(..)        => ("constants", "Constants"),
-                clean::TraitItem(..)           => ("traits", "Traits"),
-                clean::ImplItem(..)            => ("impls", "Implementations"),
-                clean::ViewItemItem(..)        => ("reexports", "Reexports"),
-                clean::TyMethodItem(..)        => ("tymethods", "Type Methods"),
-                clean::MethodItem(..)          => ("methods", "Methods"),
-                clean::StructFieldItem(..)     => ("fields", "Struct Fields"),
-                clean::VariantItem(..)         => ("variants", "Variants"),
-                clean::ForeignFunctionItem(..) => ("ffi-fns", "Foreign Functions"),
-                clean::ForeignStaticItem(..)   => ("ffi-statics", "Foreign Statics"),
-                clean::MacroItem(..)           => ("macros", "Macros"),
-                clean::PrimitiveItem(..)       => ("primitives", "Primitive Types"),
-                clean::AssociatedTypeItem(..)  => ("associated-types", "Associated Types"),
+            let (short, name) = match myty.unwrap() {
+                ItemType::Module          => ("modules", "Modules"),
+                ItemType::Struct          => ("structs", "Structs"),
+                ItemType::Enum            => ("enums", "Enums"),
+                ItemType::Function        => ("functions", "Functions"),
+                ItemType::Typedef         => ("types", "Type Definitions"),
+                ItemType::Static          => ("statics", "Statics"),
+                ItemType::Constant        => ("constants", "Constants"),
+                ItemType::Trait           => ("traits", "Traits"),
+                ItemType::Impl            => ("impls", "Implementations"),
+                ItemType::ViewItem        => ("reexports", "Reexports"),
+                ItemType::TyMethod        => ("tymethods", "Type Methods"),
+                ItemType::Method          => ("methods", "Methods"),
+                ItemType::StructField     => ("fields", "Struct Fields"),
+                ItemType::Variant         => ("variants", "Variants"),
+                ItemType::Macro           => ("macros", "Macros"),
+                ItemType::Primitive       => ("primitives", "Primitive Types"),
+                ItemType::AssociatedType  => ("associated-types", "Associated Types"),
             };
             try!(write!(w,
                         "<h2 id='{id}' class='section-header'>\
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 7c6f7ed3fe2..978af31cdc6 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -313,7 +313,8 @@
             for (var i = results.length - 1; i > 0; i -= 1) {
                 if (results[i].word === results[i - 1].word &&
                     results[i].item.ty === results[i - 1].item.ty &&
-                    results[i].item.path === results[i - 1].item.path)
+                    results[i].item.path === results[i - 1].item.path &&
+                    (results[i].item.parent || {}).name === (results[i - 1].item.parent || {}).name)
                 {
                     results[i].id = -1;
                 }
@@ -566,8 +567,8 @@
                          "method",
                          "structfield",
                          "variant",
-                         "ffi",
-                         "ffs",
+                         "ffi", // retained for backward compatibility
+                         "ffs", // retained for backward compatibility
                          "macro",
                          "primitive",
                          "associatedtype",
@@ -707,8 +708,8 @@
                 var code = $('<code>').append(structs[j]);
                 $.each(code.find('a'), function(idx, a) {
                     var href = $(a).attr('href');
-                    if (!href.startsWith('http')) {
-                        $(a).attr('href', rootPath + $(a).attr('href'));
+                    if (href && !href.startsWith('http')) {
+                        $(a).attr('href', rootPath + href);
                     }
                 });
                 var li = $('<li>').append(code);
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index cc946a6ca4a..66108bea988 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -12,6 +12,10 @@
 #![experimental]
 #![crate_type = "dylib"]
 #![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+       html_root_url = "http://doc.rust-lang.org/nightly/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![allow(unknown_features)]
 #![feature(globs, if_let, macro_rules, phase, slicing_syntax, tuple_indexing)]
@@ -21,6 +25,7 @@ extern crate getopts;
 extern crate libc;
 extern crate rustc;
 extern crate rustc_trans;
+extern crate rustc_driver;
 extern crate serialize;
 extern crate syntax;
 extern crate "test" as testing;
@@ -163,7 +168,7 @@ pub fn main_args(args: &[String]) -> int {
         usage(args[0].as_slice());
         return 0;
     } else if matches.opt_present("version") {
-        match rustc_trans::driver::version("rustdoc", &matches) {
+        match rustc_driver::version("rustdoc", &matches) {
             Some(err) => {
                 println!("{}", err);
                 return 1
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 2a5972bb3d9..7ca7ae4b211 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -19,7 +19,7 @@ use std::string::String;
 use std::collections::{HashSet, HashMap};
 use testing;
 use rustc::session::{mod, config};
-use rustc_trans::driver::driver;
+use rustc_driver::driver;
 use syntax::ast;
 use syntax::codemap::{CodeMap, dummy_spanned};
 use syntax::diagnostic;
@@ -42,7 +42,7 @@ pub fn run(input: &str,
            crate_name: Option<String>)
            -> int {
     let input_path = Path::new(input);
-    let input = driver::FileInput(input_path.clone());
+    let input = config::Input::File(input_path.clone());
 
     let sessopts = config::Options {
         maybe_sysroot: Some(os::self_exe_path().unwrap().dir_path()),
@@ -110,7 +110,7 @@ fn runtest(test: &str, cratename: &str, libs: Vec<Path>, externs: core::Externs,
     // the test harness wants its own `main` & top level functions, so
     // never wrap the test in `fn main() { ... }`
     let test = maketest(test, Some(cratename), true, as_test_harness);
-    let input = driver::StrInput(test.to_string());
+    let input = config::Input::Str(test.to_string());
 
     let sessopts = config::Options {
         maybe_sysroot: Some(os::self_exe_path().unwrap().dir_path()),
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 403ca9d1432..8fc3c23e88f 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -19,7 +19,8 @@ use core::kinds::Sized;
 use fmt;
 use iter::IteratorExt;
 use mem;
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use slice::{SlicePrelude, AsSlice};
 use str::{Str, StrPrelude};
 use string::{String, IntoString};
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index d8023dd3e4e..8a90c06f038 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -149,9 +149,9 @@ macro_rules! bitflags {
             #[inline]
             pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
                 if (bits & !$BitFlags::all().bits()) != 0 {
-                    ::std::option::None
+                    ::std::option::Option::None
                 } else {
-                    ::std::option::Some($BitFlags { bits: bits })
+                    ::std::option::Option::Some($BitFlags { bits: bits })
                 }
             }
 
@@ -261,7 +261,7 @@ macro_rules! bitflags {
 #[allow(non_upper_case_globals)]
 mod tests {
     use hash;
-    use option::{Some, None};
+    use option::Option::{Some, None};
     use ops::{BitOr, BitAnd, BitXor, Sub, Not};
 
     bitflags! {
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
index 1f94d7b4fa6..f89876f7245 100644
--- a/src/libstd/c_vec.rs
+++ b/src/libstd/c_vec.rs
@@ -38,7 +38,8 @@
 use kinds::Send;
 use mem;
 use ops::Drop;
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use ptr::RawPtr;
 use ptr;
 use raw;
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index cf09c93f917..8f879bd50d0 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -25,8 +25,10 @@ use kinds::Sized;
 use mem::{mod, replace};
 use num::{Int, UnsignedInt};
 use ops::{Deref, Index, IndexMut};
-use option::{Some, None, Option};
-use result::{Result, Ok, Err};
+use option::Option;
+use option::Option::{Some, None};
+use result::Result;
+use result::Result::{Ok, Err};
 
 use super::table;
 use super::table::{
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index b40622171d5..fd32d207e79 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -19,8 +19,8 @@ use fmt;
 use hash::{Hash, Hasher, RandomSipHasher};
 use iter::{Iterator, IteratorExt, FromIterator, FilterMap, Chain, Repeat, Zip, Extend, repeat};
 use iter;
-use option::{Some, None};
-use result::{Ok, Err};
+use option::Option::{Some, None};
+use result::Result::{Ok, Err};
 
 use super::map::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY};
 
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index f41ccea0aaf..de06a1e0bbd 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -21,7 +21,8 @@ use mem::{min_align_of, size_of};
 use mem;
 use num::{Int, UnsignedInt};
 use ops::{Deref, DerefMut, Drop};
-use option::{Some, None, Option};
+use option::Option;
+use option::Option::{Some, None};
 use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory};
 use ptr;
 use rt::heap::{allocate, deallocate};
diff --git a/src/libstd/collections/lru_cache.rs b/src/libstd/collections/lru_cache.rs
index 94bea37d187..adbc135364b 100644
--- a/src/libstd/collections/lru_cache.rs
+++ b/src/libstd/collections/lru_cache.rs
@@ -44,10 +44,11 @@ use hash::Hash;
 use iter::{range, Iterator, Extend};
 use mem;
 use ops::Drop;
-use option::{Some, None, Option};
+use option::Option;
+use option::Option::{Some, None};
 use boxed::Box;
 use ptr;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 
 // FIXME(conventions): implement iterators?
 // FIXME(conventions): implement indexing?
diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs
index 2b66e91c00d..d291ed72567 100644
--- a/src/libstd/comm/mod.rs
+++ b/src/libstd/comm/mod.rs
@@ -354,6 +354,8 @@ mod select;
 mod shared;
 mod stream;
 mod sync;
+mod mpsc_queue;
+mod spsc_queue;
 
 /// The receiving-half of Rust's channel type. This half can only be owned by
 /// one task
@@ -628,24 +630,26 @@ impl<T: Send> Sender<T> {
 #[unstable]
 impl<T: Send> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
-        let (packet, sleeper) = match *unsafe { self.inner() } {
+        let (packet, sleeper, guard) = match *unsafe { self.inner() } {
             Oneshot(ref p) => {
                 let a = Arc::new(UnsafeCell::new(shared::Packet::new()));
                 unsafe {
-                    (*a.get()).postinit_lock();
+                    let guard = (*a.get()).postinit_lock();
                     match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) {
-                        oneshot::UpSuccess | oneshot::UpDisconnected => (a, None),
-                        oneshot::UpWoke(task) => (a, Some(task))
+                        oneshot::UpSuccess |
+                        oneshot::UpDisconnected => (a, None, guard),
+                        oneshot::UpWoke(task) => (a, Some(task), guard)
                     }
                 }
             }
             Stream(ref p) => {
                 let a = Arc::new(UnsafeCell::new(shared::Packet::new()));
                 unsafe {
-                    (*a.get()).postinit_lock();
+                    let guard = (*a.get()).postinit_lock();
                     match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) {
-                        stream::UpSuccess | stream::UpDisconnected => (a, None),
-                        stream::UpWoke(task) => (a, Some(task)),
+                        stream::UpSuccess |
+                        stream::UpDisconnected => (a, None, guard),
+                        stream::UpWoke(task) => (a, Some(task), guard),
                     }
                 }
             }
@@ -657,7 +661,7 @@ impl<T: Send> Clone for Sender<T> {
         };
 
         unsafe {
-            (*packet.get()).inherit_blocker(sleeper);
+            (*packet.get()).inherit_blocker(sleeper, guard);
 
             let tmp = Sender::new(Shared(packet.clone()));
             mem::swap(self.inner_mut(), tmp.inner_mut());
diff --git a/src/libstd/sync/mpsc_queue.rs b/src/libstd/comm/mpsc_queue.rs
index 09212e4dfb6..d4249abc3dd 100644
--- a/src/libstd/sync/mpsc_queue.rs
+++ b/src/libstd/comm/mpsc_queue.rs
@@ -132,15 +132,6 @@ impl<T: Send> Queue<T> {
             if self.head.load(Acquire) == tail {Empty} else {Inconsistent}
         }
     }
-
-    /// Attempts to pop data from this queue, but doesn't attempt too hard. This
-    /// will canonicalize inconsistent states to a `None` value.
-    pub fn casual_pop(&self) -> Option<T> {
-        match self.pop() {
-            Data(t) => Some(t),
-            Empty | Inconsistent => None,
-        }
-    }
 }
 
 #[unsafe_destructor]
diff --git a/src/libstd/comm/shared.rs b/src/libstd/comm/shared.rs
index 6396edbdbd1..13b5e10fcd3 100644
--- a/src/libstd/comm/shared.rs
+++ b/src/libstd/comm/shared.rs
@@ -26,12 +26,11 @@ use alloc::boxed::Box;
 use core::cmp;
 use core::int;
 use rustrt::local::Local;
-use rustrt::mutex::NativeMutex;
 use rustrt::task::{Task, BlockedTask};
 use rustrt::thread::Thread;
 
-use sync::atomic;
-use sync::mpsc_queue as mpsc;
+use sync::{atomic, Mutex, MutexGuard};
+use comm::mpsc_queue as mpsc;
 
 const DISCONNECTED: int = int::MIN;
 const FUDGE: int = 1024;
@@ -56,7 +55,7 @@ pub struct Packet<T> {
 
     // this lock protects various portions of this implementation during
     // select()
-    select_lock: NativeMutex,
+    select_lock: Mutex<()>,
 }
 
 pub enum Failure {
@@ -76,7 +75,7 @@ impl<T: Send> Packet<T> {
             channels: atomic::AtomicInt::new(2),
             port_dropped: atomic::AtomicBool::new(false),
             sender_drain: atomic::AtomicInt::new(0),
-            select_lock: unsafe { NativeMutex::new() },
+            select_lock: Mutex::new(()),
         };
         return p;
     }
@@ -86,8 +85,8 @@ impl<T: Send> Packet<T> {
     // In other case mutex data will be duplicated while cloning
     // and that could cause problems on platforms where it is
     // represented by opaque data structure
-    pub fn postinit_lock(&mut self) {
-        unsafe { self.select_lock.lock_noguard() }
+    pub fn postinit_lock(&self) -> MutexGuard<()> {
+        self.select_lock.lock()
     }
 
     // This function is used at the creation of a shared packet to inherit a
@@ -95,7 +94,9 @@ impl<T: Send> Packet<T> {
     // tasks in select().
     //
     // This can only be called at channel-creation time
-    pub fn inherit_blocker(&mut self, task: Option<BlockedTask>) {
+    pub fn inherit_blocker(&mut self,
+                           task: Option<BlockedTask>,
+                           guard: MutexGuard<()>) {
         match task {
             Some(task) => {
                 assert_eq!(self.cnt.load(atomic::SeqCst), 0);
@@ -135,7 +136,7 @@ impl<T: Send> Packet<T> {
         // interfere with this method. After we unlock this lock, we're
         // signifying that we're done modifying self.cnt and self.to_wake and
         // the port is ready for the world to continue using it.
-        unsafe { self.select_lock.unlock_noguard() }
+        drop(guard);
     }
 
     pub fn send(&mut self, t: T) -> Result<(), T> {
@@ -441,7 +442,7 @@ impl<T: Send> Packet<T> {
         // done with. Without this bounce, we can race with inherit_blocker
         // about looking at and dealing with to_wake. Once we have acquired the
         // lock, we are guaranteed that inherit_blocker is done.
-        unsafe {
+        {
             let _guard = self.select_lock.lock();
         }
 
diff --git a/src/libstd/sync/spsc_queue.rs b/src/libstd/comm/spsc_queue.rs
index f0eabe61737..a6b4ab71bac 100644
--- a/src/libstd/sync/spsc_queue.rs
+++ b/src/libstd/comm/spsc_queue.rs
@@ -40,7 +40,6 @@ use core::prelude::*;
 use alloc::boxed::Box;
 use core::mem;
 use core::cell::UnsafeCell;
-use alloc::arc::Arc;
 
 use sync::atomic::{AtomicPtr, Relaxed, AtomicUint, Acquire, Release};
 
@@ -74,39 +73,6 @@ pub struct Queue<T> {
     cache_subtractions: AtomicUint,
 }
 
-/// A safe abstraction for the consumer in a single-producer single-consumer
-/// queue.
-pub struct Consumer<T> {
-    inner: Arc<Queue<T>>
-}
-
-impl<T: Send> Consumer<T> {
-    /// Attempts to pop the value from the head of the queue, returning `None`
-    /// if the queue is empty.
-    pub fn pop(&mut self) -> Option<T> {
-        self.inner.pop()
-    }
-
-    /// Attempts to peek at the head of the queue, returning `None` if the queue
-    /// is empty.
-    pub fn peek<'a>(&'a mut self) -> Option<&'a mut T> {
-        self.inner.peek()
-    }
-}
-
-/// A safe abstraction for the producer in a single-producer single-consumer
-/// queue.
-pub struct Producer<T> {
-    inner: Arc<Queue<T>>
-}
-
-impl<T: Send> Producer<T> {
-    /// Pushes a new value onto the queue.
-    pub fn push(&mut self, t: T) {
-        self.inner.push(t)
-    }
-}
-
 impl<T: Send> Node<T> {
     fn new() -> *mut Node<T> {
         unsafe {
@@ -118,30 +84,6 @@ impl<T: Send> Node<T> {
     }
 }
 
-/// Creates a new queue with a consumer-producer pair.
-///
-/// The producer returned is connected to the consumer to push all data to
-/// the consumer.
-///
-/// # Arguments
-///
-///   * `bound` - This queue implementation is implemented with a linked
-///               list, and this means that a push is always a malloc. In
-///               order to amortize this cost, an internal cache of nodes is
-///               maintained to prevent a malloc from always being
-///               necessary. This bound is the limit on the size of the
-///               cache (if desired). If the value is 0, then the cache has
-///               no bound. Otherwise, the cache will never grow larger than
-///               `bound` (although the queue itself could be much larger.
-pub fn queue<T: Send>(bound: uint) -> (Consumer<T>, Producer<T>) {
-    let q = unsafe { Queue::new(bound) };
-    let arc = Arc::new(q);
-    let consumer = Consumer { inner: arc.clone() };
-    let producer = Producer { inner: arc };
-
-    (consumer, producer)
-}
-
 impl<T: Send> Queue<T> {
     /// Creates a new queue.
     ///
@@ -296,78 +238,88 @@ impl<T: Send> Drop for Queue<T> {
 mod test {
     use prelude::*;
 
-    use super::{queue};
+    use sync::Arc;
+    use super::Queue;
 
     #[test]
     fn smoke() {
-        let (mut consumer, mut producer) = queue(0);
-        producer.push(1i);
-        producer.push(2);
-        assert_eq!(consumer.pop(), Some(1i));
-        assert_eq!(consumer.pop(), Some(2));
-        assert_eq!(consumer.pop(), None);
-        producer.push(3);
-        producer.push(4);
-        assert_eq!(consumer.pop(), Some(3));
-        assert_eq!(consumer.pop(), Some(4));
-        assert_eq!(consumer.pop(), None);
+        unsafe {
+            let queue = Queue::new(0);
+            queue.push(1i);
+            queue.push(2);
+            assert_eq!(queue.pop(), Some(1i));
+            assert_eq!(queue.pop(), Some(2));
+            assert_eq!(queue.pop(), None);
+            queue.push(3);
+            queue.push(4);
+            assert_eq!(queue.pop(), Some(3));
+            assert_eq!(queue.pop(), Some(4));
+            assert_eq!(queue.pop(), None);
+        }
     }
 
     #[test]
     fn peek() {
-        let (mut consumer, mut producer) = queue(0);
-        producer.push(vec![1i]);
+        unsafe {
+            let queue = Queue::new(0);
+            queue.push(vec![1i]);
+
+            // Ensure the borrowchecker works
+            match queue.peek() {
+                Some(vec) => match vec.as_slice() {
+                    // Note that `pop` is not allowed here due to borrow
+                    [1] => {}
+                    _ => return
+                },
+                None => unreachable!()
+            }
 
-        // Ensure the borrowchecker works
-        match consumer.peek() {
-            Some(vec) => match vec.as_slice() {
-                // Note that `pop` is not allowed here due to borrow
-                [1] => {}
-                _ => return
-            },
-            None => unreachable!()
+            queue.pop();
         }
-
-        consumer.pop();
     }
 
     #[test]
     fn drop_full() {
-        let (_, mut producer) = queue(0);
-        producer.push(box 1i);
-        producer.push(box 2i);
+        unsafe {
+            let q = Queue::new(0);
+            q.push(box 1i);
+            q.push(box 2i);
+        }
     }
 
     #[test]
     fn smoke_bound() {
-        let (mut consumer, mut producer) = queue(1);
-        producer.push(1i);
-        producer.push(2);
-        assert_eq!(consumer.pop(), Some(1));
-        assert_eq!(consumer.pop(), Some(2));
-        assert_eq!(consumer.pop(), None);
-        producer.push(3);
-        producer.push(4);
-        assert_eq!(consumer.pop(), Some(3));
-        assert_eq!(consumer.pop(), Some(4));
-        assert_eq!(consumer.pop(), None);
+        unsafe {
+            let q = Queue::new(0);
+            q.push(1i);
+            q.push(2);
+            assert_eq!(q.pop(), Some(1));
+            assert_eq!(q.pop(), Some(2));
+            assert_eq!(q.pop(), None);
+            q.push(3);
+            q.push(4);
+            assert_eq!(q.pop(), Some(3));
+            assert_eq!(q.pop(), Some(4));
+            assert_eq!(q.pop(), None);
+        }
     }
 
     #[test]
     fn stress() {
-        stress_bound(0);
-        stress_bound(1);
+        unsafe {
+            stress_bound(0);
+            stress_bound(1);
+        }
 
-        fn stress_bound(bound: uint) {
-            let (consumer, mut producer) = queue(bound);
+        unsafe fn stress_bound(bound: uint) {
+            let q = Arc::new(Queue::new(bound));
 
             let (tx, rx) = channel();
+            let q2 = q.clone();
             spawn(proc() {
-                // Move the consumer to a local mutable slot
-                let mut consumer = consumer;
                 for _ in range(0u, 100000) {
                     loop {
-                        match consumer.pop() {
+                        match q2.pop() {
                             Some(1i) => break,
                             Some(_) => panic!(),
                             None => {}
@@ -377,7 +329,7 @@ mod test {
                 tx.send(());
             });
             for _ in range(0i, 100000) {
-                producer.push(1);
+                q.push(1);
             }
             rx.recv();
         }
diff --git a/src/libstd/comm/stream.rs b/src/libstd/comm/stream.rs
index 23d042960b1..06ab4f4427a 100644
--- a/src/libstd/comm/stream.rs
+++ b/src/libstd/comm/stream.rs
@@ -32,7 +32,7 @@ use rustrt::task::{Task, BlockedTask};
 use rustrt::thread::Thread;
 
 use sync::atomic;
-use sync::spsc_queue as spsc;
+use comm::spsc_queue as spsc;
 use comm::Receiver;
 
 const DISCONNECTED: int = int::MIN;
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 3cd0c0eeaf2..aa0c8b53c2e 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -225,8 +225,8 @@ pub mod dl {
     }
 
     pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
-        use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
+        use sync::{StaticMutex, MUTEX_INIT};
+        static LOCK: StaticMutex = MUTEX_INIT;
         unsafe {
             // dlerror isn't thread safe, so we need to lock around this entire
             // sequence
@@ -280,7 +280,8 @@ pub mod dl {
     use libc;
     use os;
     use ptr;
-    use result::{Ok, Err, Result};
+    use result::Result;
+    use result::Result::{Ok, Err};
     use slice::SlicePrelude;
     use str::StrPrelude;
     use str;
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 82ad893f88a..9ad2655f6e9 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -78,7 +78,8 @@
 //! }
 //! ```
 
-use option::{Option, None};
+use option::Option;
+use option::Option::None;
 use kinds::Send;
 use string::String;
 
diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs
index d839c1484e5..58a41f4d7d5 100644
--- a/src/libstd/failure.rs
+++ b/src/libstd/failure.rs
@@ -16,8 +16,9 @@ use cell::RefCell;
 use fmt;
 use io::{Writer, IoResult};
 use kinds::Send;
-use option::{Some, None, Option};
-use result::Ok;
+use option::Option;
+use option::Option::{Some, None};
+use result::Result::Ok;
 use rt::backtrace;
 use rustrt::{Stderr, Stdio};
 use rustrt::local::Local;
diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs
index 7e1bfd704a9..6a2047d1cef 100644
--- a/src/libstd/fmt.rs
+++ b/src/libstd/fmt.rs
@@ -406,7 +406,7 @@
 
 use io::Writer;
 use io;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use string;
 use vec::Vec;
 
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index fba9e4f2e25..0b2c6843c96 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -16,8 +16,9 @@ use cmp;
 use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
 use iter::ExactSizeIterator;
 use ops::Drop;
-use option::{Some, None, Option};
-use result::{Ok, Err};
+use option::Option;
+use option::Option::{Some, None};
+use result::Result::{Ok, Err};
 use slice::{SlicePrelude};
 use slice;
 use vec::Vec;
diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs
index a90b6bbbb8e..3de0a7be95e 100644
--- a/src/libstd/io/comm_adapters.rs
+++ b/src/libstd/io/comm_adapters.rs
@@ -12,8 +12,8 @@ use clone::Clone;
 use cmp;
 use comm::{Sender, Receiver};
 use io;
-use option::{None, Some};
-use result::{Ok, Err};
+use option::Option::{None, Some};
+use result::Result::{Ok, Err};
 use slice::{bytes, CloneSliceAllocPrelude, SlicePrelude};
 use super::{Buffer, Reader, Writer, IoResult};
 use vec::Vec;
diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs
index 4b2ffb4d559..1bdf99f6d6d 100644
--- a/src/libstd/io/extensions.rs
+++ b/src/libstd/io/extensions.rs
@@ -19,9 +19,10 @@ use io::{IoError, IoResult, Reader};
 use io;
 use iter::Iterator;
 use num::Int;
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use ptr::RawPtr;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use slice::{SlicePrelude, AsSlice};
 
 /// An iterator that reads a single byte on each iteration,
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index fd6b57d096a..86b2dc4d940 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -53,15 +53,17 @@
 use clone::Clone;
 use io::standard_error;
 use io::{FilePermission, Write, Open, FileAccess, FileMode, FileType};
-use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader};
+use io::{IoResult, IoError, InvalidInput};
+use io::{FileStat, SeekStyle, Seek, Writer, Reader};
 use io::{Read, Truncate, ReadWrite, Append};
 use io::UpdateIoError;
 use io;
 use iter::{Iterator, Extend};
-use option::{Some, None, Option};
+use option::Option;
+use option::Option::{Some, None};
 use path::{Path, GenericPath};
 use path;
-use result::{Err, Ok};
+use result::Result::{Err, Ok};
 use slice::SlicePrelude;
 use string::String;
 use vec::Vec;
@@ -134,13 +136,26 @@ impl File {
     pub fn open_mode(path: &Path,
                      mode: FileMode,
                      access: FileAccess) -> IoResult<File> {
-        fs_imp::open(path, mode, access).map(|fd| {
-            File {
-                path: path.clone(),
-                fd: fd,
-                last_nread: -1
+        fs_imp::open(path, mode, access).and_then(|fd| {
+            // On *BSD systems, we can open a directory as a file and read from it:
+            // fd=open("/tmp", O_RDONLY); read(fd, buf, N);
+            // due to an old tradition before the introduction of opendir(3).
+            // We explicitly reject it because there are few use cases.
+            if cfg!(not(any(windows, target_os = "linux", target_os = "android"))) &&
+               try!(fd.fstat()).kind == FileType::Directory {
+                Err(IoError {
+                    kind: InvalidInput,
+                    desc: "is a directory",
+                    detail: None
+                })
+            } else {
+                Ok(File {
+                    path: path.clone(),
+                    fd: fd,
+                    last_nread: -1
+                })
             }
-        }).update_err("couldn't open file", |e| {
+        }).update_err("couldn't open path as file", |e| {
             format!("{}; path={}; mode={}; access={}", e, path.display(),
                 mode_string(mode), access_string(access))
         })
@@ -237,7 +252,7 @@ impl File {
     }
 
     /// Queries information about the underlying file.
-    pub fn stat(&mut self) -> IoResult<FileStat> {
+    pub fn stat(&self) -> IoResult<FileStat> {
         self.fd.fstat()
             .update_err("couldn't fstat file", |e|
                 format!("{}; path={}", e, self.path.display()))
@@ -886,7 +901,7 @@ mod test {
         let filename = &tmpdir.join("file_that_does_not_exist.txt");
         let result = File::open_mode(filename, Open, Read);
 
-        error!(result, "couldn't open file");
+        error!(result, "couldn't open path as file");
         if cfg!(unix) {
             error!(result, "no such file or directory");
         }
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index 6a9b10d2a7b..43e02d62b0b 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -15,8 +15,8 @@
 #![allow(deprecated)]
 
 use cmp::min;
-use option::None;
-use result::{Err, Ok};
+use option::Option::None;
+use result::Result::{Err, Ok};
 use io;
 use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
 use slice::{mod, AsSlice, SlicePrelude};
@@ -278,20 +278,29 @@ impl<'a> BufWriter<'a> {
 
 impl<'a> Writer for BufWriter<'a> {
     #[inline]
-    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        // return an error if the entire write does not fit in the buffer
-        let cap = if self.pos >= self.buf.len() { 0 } else { self.buf.len() - self.pos };
-        if buf.len() > cap {
-            return Err(IoError {
-                kind: io::OtherIoError,
-                desc: "Trying to write past end of buffer",
-                detail: None
-            })
+    fn write(&mut self, src: &[u8]) -> IoResult<()> {
+        let dst = self.buf[mut self.pos..];
+        let dst_len = dst.len();
+
+        if dst_len == 0 {
+            return Err(io::standard_error(io::EndOfFile));
         }
 
-        slice::bytes::copy_memory(self.buf[mut self.pos..], buf);
-        self.pos += buf.len();
-        Ok(())
+        let src_len = src.len();
+
+        if dst_len >= src_len {
+            slice::bytes::copy_memory(dst, src);
+
+            self.pos += src_len;
+
+            Ok(())
+        } else {
+            slice::bytes::copy_memory(dst, src[..dst_len]);
+
+            self.pos += dst_len;
+
+            Err(io::standard_error(io::ShortWrite(dst_len)))
+        }
     }
 }
 
@@ -302,7 +311,7 @@ impl<'a> Seek for BufWriter<'a> {
     #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
-        self.pos = new as uint;
+        self.pos = min(new as uint, self.buf.len());
         Ok(())
     }
 }
@@ -315,10 +324,10 @@ impl<'a> Seek for BufWriter<'a> {
 /// # #![allow(unused_must_use)]
 /// use std::io::BufReader;
 ///
-/// let mut buf = [0, 1, 2, 3];
-/// let mut r = BufReader::new(&mut buf);
+/// let buf = [0, 1, 2, 3];
+/// let mut r = BufReader::new(&buf);
 ///
-/// assert_eq!(r.read_to_end().unwrap(), vec!(0, 1, 2, 3));
+/// assert_eq!(r.read_to_end().unwrap(), vec![0, 1, 2, 3]);
 /// ```
 pub struct BufReader<'a> {
     buf: &'a [u8],
@@ -419,7 +428,7 @@ mod test {
 
     #[test]
     fn test_buf_writer() {
-        let mut buf = [0 as u8, ..8];
+        let mut buf = [0 as u8, ..9];
         {
             let mut writer = BufWriter::new(&mut buf);
             assert_eq!(writer.tell(), Ok(0));
@@ -431,9 +440,10 @@ mod test {
             writer.write(&[]).unwrap();
             assert_eq!(writer.tell(), Ok(8));
 
-            assert!(writer.write(&[1]).is_err());
+            assert_eq!(writer.write(&[8, 9]).unwrap_err().kind, io::ShortWrite(1));
+            assert_eq!(writer.write(&[10]).unwrap_err().kind, io::EndOfFile);
         }
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
+        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
         assert_eq!(buf.as_slice(), b);
     }
 
@@ -474,7 +484,7 @@ mod test {
 
         match writer.write(&[0, 0]) {
             Ok(..) => panic!(),
-            Err(e) => assert_eq!(e.kind, io::OtherIoError),
+            Err(e) => assert_eq!(e.kind, io::ShortWrite(1)),
         }
     }
 
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 5ed10eab15b..e0857fd27ff 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -32,7 +32,7 @@
 //!     ```rust
 //!     use std::io;
 //!
-//!     for line in io::stdin().lines() {
+//!     for line in io::stdin().lock().lines() {
 //!         print!("{}", line.unwrap());
 //!     }
 //!     ```
@@ -233,10 +233,12 @@ use int;
 use iter::{Iterator, IteratorExt};
 use mem::transmute;
 use ops::{BitOr, BitXor, BitAnd, Sub, Not};
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use os;
 use boxed::Box;
-use result::{Ok, Err, Result};
+use result::Result;
+use result::Result::{Ok, Err};
 use sys;
 use slice::{AsSlice, SlicePrelude};
 use str::{Str, StrPrelude};
@@ -1413,10 +1415,10 @@ pub trait Buffer: Reader {
     /// # Example
     ///
     /// ```rust
-    /// use std::io;
+    /// use std::io::BufReader;
     ///
-    /// let mut reader = io::stdin();
-    /// let input = reader.read_line().ok().unwrap_or("nothing".to_string());
+    /// let mut reader = BufReader::new(b"hello\nworld");
+    /// assert_eq!("hello\n", &*reader.read_line().unwrap());
     /// ```
     ///
     /// # Error
diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs
index 7de78692130..fea8372733c 100644
--- a/src/libstd/io/net/addrinfo.rs
+++ b/src/libstd/io/net/addrinfo.rs
@@ -22,7 +22,8 @@ pub use self::Protocol::*;
 use iter::IteratorExt;
 use io::{IoResult};
 use io::net::ip::{SocketAddr, IpAddr};
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use sys;
 use vec::Vec;
 
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index 4812e911cc4..9c0fbbe274b 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -21,8 +21,9 @@ use fmt;
 use io::{mod, IoResult, IoError};
 use io::net;
 use iter::{Iterator, IteratorExt};
-use option::{Option, None, Some};
-use result::{Ok, Err};
+use option::Option;
+use option::Option::{None, Some};
+use result::Result::{Ok, Err};
 use str::{FromStr, StrPrelude};
 use slice::{CloneSlicePrelude, SlicePrelude};
 use vec::Vec;
diff --git a/src/libstd/io/net/mod.rs b/src/libstd/io/net/mod.rs
index 5b1747876d7..09e5639bea9 100644
--- a/src/libstd/io/net/mod.rs
+++ b/src/libstd/io/net/mod.rs
@@ -11,8 +11,8 @@
 //! Networking I/O
 
 use io::{IoError, IoResult, InvalidInput};
-use option::None;
-use result::{Ok, Err};
+use option::Option::None;
+use result::Result::{Ok, Err};
 use self::ip::{SocketAddr, ToSocketAddr};
 
 pub use self::addrinfo::get_host_addresses;
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index aa223417591..a7b1b077eff 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -19,11 +19,12 @@
 
 use clone::Clone;
 use io::IoResult;
-use result::Err;
+use result::Result::Err;
 use io::net::ip::{SocketAddr, ToSocketAddr};
 use io::{Reader, Writer, Listener, Acceptor};
 use io::{standard_error, TimedOut};
-use option::{None, Some, Option};
+use option::Option;
+use option::Option::{None, Some};
 use time::Duration;
 
 use sys::tcp::TcpStream as TcpStreamImp;
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index a7239ca0f2f..a2ad365dd2a 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -19,7 +19,7 @@ use clone::Clone;
 use io::net::ip::{SocketAddr, IpAddr, ToSocketAddr};
 use io::{Reader, Writer, IoResult};
 use option::Option;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use sys::udp::UdpSocket as UdpSocketImp;
 use sys_common;
 
diff --git a/src/libstd/io/result.rs b/src/libstd/io/result.rs
index 305bcf9ecbc..32965d23971 100644
--- a/src/libstd/io/result.rs
+++ b/src/libstd/io/result.rs
@@ -15,7 +15,7 @@
 //! as a `Reader` without unwrapping the result first.
 
 use clone::Clone;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle, IoResult};
 
 impl<W: Writer> Writer for IoResult<W> {
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 665000eae88..cf2df0da7fe 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -29,22 +29,28 @@ use self::StdSource::*;
 
 use boxed::Box;
 use cell::RefCell;
+use clone::Clone;
 use failure::LOCAL_STDERR;
 use fmt;
-use io::{Reader, Writer, IoResult, IoError, OtherIoError,
+use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
          standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
 use kinds::Send;
 use libc;
 use mem;
-use option::{Option, Some, None};
-use result::{Ok, Err};
+use option::Option;
+use option::Option::{Some, None};
+use ops::{Deref, DerefMut};
+use result::Result::{Ok, Err};
 use rustrt;
 use rustrt::local::Local;
 use rustrt::task::Task;
 use slice::SlicePrelude;
 use str::StrPrelude;
+use string::String;
 use sys::{fs, tty};
+use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT};
 use uint;
+use vec::Vec;
 
 // And so begins the tale of acquiring a uv handle to a stdio stream on all
 // platforms in all situations. Our story begins by splitting the world into two
@@ -90,28 +96,135 @@ thread_local!(static LOCAL_STDOUT: RefCell<Option<Box<Writer + Send>>> = {
     RefCell::new(None)
 })
 
-/// Creates a new non-blocking handle to the stdin of the current process.
-///
-/// The returned handled is buffered by default with a `BufferedReader`. If
-/// buffered access is not desired, the `stdin_raw` function is provided to
-/// provided unbuffered access to stdin.
+/// A synchronized wrapper around a buffered reader from stdin
+#[deriving(Clone)]
+pub struct StdinReader {
+    inner: Arc<Mutex<BufferedReader<StdReader>>>,
+}
+
+/// A guard for exlusive access to `StdinReader`'s internal `BufferedReader`.
+pub struct StdinReaderGuard<'a> {
+    inner: MutexGuard<'a, BufferedReader<StdReader>>,
+}
+
+impl<'a> Deref<BufferedReader<StdReader>> for StdinReaderGuard<'a> {
+    fn deref(&self) -> &BufferedReader<StdReader> {
+        &*self.inner
+    }
+}
+
+impl<'a> DerefMut<BufferedReader<StdReader>> for StdinReaderGuard<'a> {
+    fn deref_mut(&mut self) -> &mut BufferedReader<StdReader> {
+        &mut *self.inner
+    }
+}
+
+impl StdinReader {
+    /// Locks the `StdinReader`, granting the calling thread exclusive access
+    /// to the underlying `BufferedReader`.
+    ///
+    /// This provides access to methods like `chars` and `lines`.
+    ///
+    /// ## Example
+    ///
+    /// ```rust
+    /// use std::io;
+    ///
+    /// for line in io::stdin().lock().lines() {
+    ///     println!("{}", line.unwrap());
+    /// }
+    /// ```
+    pub fn lock<'a>(&'a mut self) -> StdinReaderGuard<'a> {
+        StdinReaderGuard {
+            inner: self.inner.lock()
+        }
+    }
+
+    /// Like `Buffer::read_line`.
+    ///
+    /// The read is performed atomically - concurrent read calls in other
+    /// threads will not interleave with this one.
+    pub fn read_line(&mut self) -> IoResult<String> {
+        self.inner.lock().read_line()
+    }
+
+    /// Like `Buffer::read_until`.
+    ///
+    /// The read is performed atomically - concurrent read calls in other
+    /// threads will not interleave with this one.
+    pub fn read_until(&mut self, byte: u8) -> IoResult<Vec<u8>> {
+        self.inner.lock().read_until(byte)
+    }
+
+    /// Like `Buffer::read_char`.
+    ///
+    /// The read is performed atomically - concurrent read calls in other
+    /// threads will not interleave with this one.
+    pub fn read_char(&mut self) -> IoResult<char> {
+        self.inner.lock().read_char()
+    }
+}
+
+impl Reader for StdinReader {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+        self.inner.lock().read(buf)
+    }
+
+    // We have to manually delegate all of these because the default impls call
+    // read more than once and we don't want those calls to interleave (or
+    // incur the costs of repeated locking).
+
+    fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult<uint> {
+        self.inner.lock().read_at_least(min, buf)
+    }
+
+    fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
+        self.inner.lock().push_at_least(min, len, buf)
+    }
+
+    fn read_to_end(&mut self) -> IoResult<Vec<u8>> {
+        self.inner.lock().read_to_end()
+    }
+
+    fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
+        self.inner.lock().read_le_uint_n(nbytes)
+    }
+
+    fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
+        self.inner.lock().read_be_uint_n(nbytes)
+    }
+}
+
+/// Creates a new handle to the stdin of the current process.
 ///
-/// Care should be taken when creating multiple handles to the stdin of a
-/// process. Because this is a buffered reader by default, it's possible for
-/// pending input to be unconsumed in one reader and unavailable to other
-/// readers. It is recommended that only one handle at a time is created for the
-/// stdin of a process.
+/// The returned handle is a wrapper around a global `BufferedReader` shared
+/// by all threads. If buffered access is not desired, the `stdin_raw` function
+/// is provided to provided unbuffered access to stdin.
 ///
 /// See `stdout()` for more notes about this function.
-pub fn stdin() -> BufferedReader<StdReader> {
-    // The default buffer capacity is 64k, but apparently windows doesn't like
-    // 64k reads on stdin. See #13304 for details, but the idea is that on
-    // windows we use a slightly smaller buffer that's been seen to be
-    // acceptable.
-    if cfg!(windows) {
-        BufferedReader::with_capacity(8 * 1024, stdin_raw())
-    } else {
-        BufferedReader::new(stdin_raw())
+pub fn stdin() -> StdinReader {
+    // We're following the same strategy as kimundi's lazy_static library
+    static mut STDIN: *const StdinReader = 0 as *const StdinReader;
+    static ONCE: Once = ONCE_INIT;
+
+    unsafe {
+        ONCE.doit(|| {
+            // The default buffer capacity is 64k, but apparently windows doesn't like
+            // 64k reads on stdin. See #13304 for details, but the idea is that on
+            // windows we use a slightly smaller buffer that's been seen to be
+            // acceptable.
+            let stdin = if cfg!(windows) {
+                BufferedReader::with_capacity(8 * 1024, stdin_raw())
+            } else {
+                BufferedReader::new(stdin_raw())
+            };
+            let stdin = StdinReader {
+                inner: Arc::new(Mutex::new(stdin))
+            };
+            STDIN = mem::transmute(box stdin);
+        });
+
+        (*STDIN).clone()
     }
 }
 
diff --git a/src/libstd/io/tempfile.rs b/src/libstd/io/tempfile.rs
index 4788ba79b7f..f3a11939995 100644
--- a/src/libstd/io/tempfile.rs
+++ b/src/libstd/io/tempfile.rs
@@ -14,10 +14,11 @@ use io::{fs, IoResult};
 use io;
 use libc;
 use ops::Drop;
-use option::{Option, None, Some};
+use option::Option;
+use option::Option::{None, Some};
 use os;
 use path::{Path, GenericPath};
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use sync::atomic;
 
 /// A wrapper for a path to temporary directory implementing automatic
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index f6b73f037f2..d4274d7e401 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -106,7 +106,7 @@
 #![allow(unknown_features)]
 #![feature(macro_rules, globs, linkage)]
 #![feature(default_type_params, phase, lang_items, unsafe_destructor)]
-#![feature(import_shadowing, slicing_syntax)]
+#![feature(import_shadowing, slicing_syntax, tuple_indexing)]
 
 // Don't link to std. We are std.
 #![no_std]
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 0abd030a163..ba9bcc05546 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -40,14 +40,16 @@ use libc::{c_void, c_int};
 use libc;
 use boxed::Box;
 use ops::Drop;
-use option::{Some, None, Option};
+use option::Option;
+use option::Option::{Some, None};
 use os;
 use path::{Path, GenericPath, BytesContainer};
 use sys;
 use sys::os as os_imp;
 use ptr::RawPtr;
 use ptr;
-use result::{Err, Ok, Result};
+use result::Result;
+use result::Result::{Err, Ok};
 use slice::{AsSlice, SlicePrelude, PartialEqSlicePrelude};
 use slice::CloneSliceAllocPrelude;
 use str::{Str, StrPrelude, StrAllocating};
@@ -160,7 +162,8 @@ pub fn getcwd() -> IoResult<Path> {
 pub mod windows {
     use libc::types::os::arch::extra::DWORD;
     use libc;
-    use option::{None, Option};
+    use option::Option;
+    use option::Option::None;
     use option;
     use os::TMPBUF_SZ;
     use slice::{SlicePrelude};
@@ -196,7 +199,7 @@ pub mod windows {
                     // set `res` to None and continue.
                     let s = String::from_utf16(sub)
                         .expect("fill_utf16_buf_and_decode: closure created invalid UTF-16");
-                    res = option::Some(s)
+                    res = option::Option::Some(s)
                 }
             }
             return res;
@@ -209,14 +212,12 @@ Accessing environment variables is not generally threadsafe.
 Serialize access through a global lock.
 */
 fn with_env_lock<T>(f: || -> T) -> T {
-    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use sync::{StaticMutex, MUTEX_INIT};
 
-    static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
+    static LOCK: StaticMutex = MUTEX_INIT;
 
-    unsafe {
-        let _guard = LOCK.lock();
-        f()
-    }
+    let _guard = LOCK.lock();
+    f()
 }
 
 /// Returns a vector of (variable, value) pairs, for all the environment
@@ -1799,7 +1800,7 @@ mod tests {
     fn test_setenv() {
         let n = make_rand_name();
         setenv(n.as_slice(), "VALUE");
-        assert_eq!(getenv(n.as_slice()), option::Some("VALUE".to_string()));
+        assert_eq!(getenv(n.as_slice()), option::Option::Some("VALUE".to_string()));
     }
 
     #[test]
@@ -1807,7 +1808,7 @@ mod tests {
         let n = make_rand_name();
         setenv(n.as_slice(), "VALUE");
         unsetenv(n.as_slice());
-        assert_eq!(getenv(n.as_slice()), option::None);
+        assert_eq!(getenv(n.as_slice()), option::Option::None);
     }
 
     #[test]
@@ -1816,9 +1817,9 @@ mod tests {
         let n = make_rand_name();
         setenv(n.as_slice(), "1");
         setenv(n.as_slice(), "2");
-        assert_eq!(getenv(n.as_slice()), option::Some("2".to_string()));
+        assert_eq!(getenv(n.as_slice()), option::Option::Some("2".to_string()));
         setenv(n.as_slice(), "");
-        assert_eq!(getenv(n.as_slice()), option::Some("".to_string()));
+        assert_eq!(getenv(n.as_slice()), option::Option::Some("".to_string()));
     }
 
     // Windows GetEnvironmentVariable requires some extra work to make sure
@@ -1835,7 +1836,7 @@ mod tests {
         let n = make_rand_name();
         setenv(n.as_slice(), s.as_slice());
         debug!("{}", s.clone());
-        assert_eq!(getenv(n.as_slice()), option::Some(s));
+        assert_eq!(getenv(n.as_slice()), option::Option::Some(s));
     }
 
     #[test]
@@ -1872,7 +1873,7 @@ mod tests {
             // MingW seems to set some funky environment variables like
             // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
             // from env() but not visible from getenv().
-            assert!(v2.is_none() || v2 == option::Some(v));
+            assert!(v2.is_none() || v2 == option::Option::Some(v));
         }
     }
 
@@ -1959,7 +1960,7 @@ mod tests {
 
     #[test]
     fn memory_map_rw() {
-        use result::{Ok, Err};
+        use result::Result::{Ok, Err};
 
         let chunk = match os::MemoryMap::new(16, &[
             os::MapReadable,
@@ -1978,7 +1979,7 @@ mod tests {
 
     #[test]
     fn memory_map_file() {
-        use result::{Ok, Err};
+        use result::Result::{Ok, Err};
         use os::*;
         use libc::*;
         use io::fs;
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index b17106e811f..01b42395471 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -66,7 +66,8 @@ use c_str::CString;
 use clone::Clone;
 use fmt;
 use iter::IteratorExt;
-use option::{Option, None, Some};
+use option::Option;
+use option::Option::{None, Some};
 use str;
 use str::{CowString, MaybeOwned, Str, StrPrelude};
 use string::String;
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index f6778588add..d6d27daf4ae 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -17,7 +17,8 @@ use hash;
 use io::Writer;
 use iter::{DoubleEndedIteratorExt, AdditiveIterator, Extend};
 use iter::{Iterator, IteratorExt, Map};
-use option::{Option, None, Some};
+use option::Option;
+use option::Option::{None, Some};
 use kinds::Sized;
 use str::{FromStr, Str};
 use str;
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 13891a63330..08e318d32b9 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -23,7 +23,8 @@ use io::Writer;
 use iter::{AdditiveIterator, DoubleEndedIteratorExt, Extend};
 use iter::{Iterator, IteratorExt, Map};
 use mem;
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use slice::{AsSlice, SlicePrelude};
 use str::{CharSplits, FromStr, Str, StrAllocating, StrVector, StrPrelude};
 use string::String;
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index da690f5d154..413d9267152 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -227,7 +227,7 @@ use io::IoResult;
 use iter::{Iterator, IteratorExt};
 use mem;
 use rc::Rc;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use vec::Vec;
 
 #[cfg(not(target_word_size="64"))]
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 2a4d8347c30..37628b65388 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -23,7 +23,7 @@ mod imp {
     use path::Path;
     use rand::Rng;
     use rand::reader::ReaderRng;
-    use result::{Ok, Err};
+    use result::Result::{Ok, Err};
     use slice::SlicePrelude;
     use mem;
     use os::errno;
@@ -173,7 +173,7 @@ mod imp {
     use mem;
     use os;
     use rand::Rng;
-    use result::{Ok};
+    use result::Result::{Ok};
     use self::libc::{c_int, size_t};
     use slice::{SlicePrelude};
 
@@ -240,7 +240,7 @@ mod imp {
     use ops::Drop;
     use os;
     use rand::Rng;
-    use result::{Ok, Err};
+    use result::Result::{Ok, Err};
     use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
     use self::libc::types::os::arch::extra::{LONG_PTR};
     use slice::{SlicePrelude};
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
index 796bf7853f7..ca6322247c2 100644
--- a/src/libstd/rand/reader.rs
+++ b/src/libstd/rand/reader.rs
@@ -12,7 +12,7 @@
 
 use io::Reader;
 use rand::Rng;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use slice::SlicePrelude;
 
 /// An RNG that reads random bytes straight from a `Reader`. This will
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 0103fe670e7..3698a91855c 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -14,9 +14,9 @@
 
 use io::{IoResult, Writer};
 use iter::{Iterator, IteratorExt};
-use option::{Some, None};
+use option::Option::{Some, None};
 use os;
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use str::{StrPrelude, from_str};
 use sync::atomic;
 use unicode::char::UnicodeChar;
@@ -236,9 +236,10 @@ mod imp {
     use io::{IoResult, Writer};
     use libc;
     use mem;
-    use option::{Some, None, Option};
-    use result::{Ok, Err};
-    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use option::Option;
+    use option::Option::{Some, None};
+    use result::Result::{Ok, Err};
+    use sync::{StaticMutex, MUTEX_INIT};
 
     /// As always - iOS on arm uses SjLj exceptions and
     /// _Unwind_Backtrace is even not available there. Still,
@@ -264,8 +265,8 @@ mod imp {
         // while it doesn't requires lock for work as everything is
         // local, it still displays much nicer backtraces when a
         // couple of tasks panic simultaneously
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        let _g = unsafe { LOCK.lock() };
+        static LOCK: StaticMutex = MUTEX_INIT;
+        let _g = LOCK.lock();
 
         try!(writeln!(w, "stack backtrace:"));
         // 100 lines should be enough
@@ -297,8 +298,8 @@ mod imp {
         // is semi-reasonable in terms of printing anyway, and we know that all
         // I/O done here is blocking I/O, not green I/O, so we don't have to
         // worry about this being a native vs green mutex.
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        let _g = unsafe { LOCK.lock() };
+        static LOCK: StaticMutex = MUTEX_INIT;
+        let _g = LOCK.lock();
 
         try!(writeln!(w, "stack backtrace:"));
 
@@ -664,10 +665,10 @@ mod imp {
     use libc;
     use mem;
     use ops::Drop;
-    use option::{Some, None};
+    use option::Option::{Some, None};
     use path::Path;
-    use result::{Ok, Err};
-    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use result::Result::{Ok, Err};
+    use sync::{StaticMutex, MUTEX_INIT};
     use slice::SlicePrelude;
     use str::StrPrelude;
     use dynamic_lib::DynamicLibrary;
@@ -928,8 +929,8 @@ mod imp {
     pub fn write(w: &mut Writer) -> IoResult<()> {
         // According to windows documentation, all dbghelp functions are
         // single-threaded.
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        let _g = unsafe { LOCK.lock() };
+        static LOCK: StaticMutex = MUTEX_INIT;
+        let _g = LOCK.lock();
 
         // Open up dbghelp.dll, we don't link to it explicitly because it can't
         // always be found. Additionally, it's nice having fewer dependencies.
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 92657d1b59b..ce359c7b0e0 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 use libc::uintptr_t;
-use option::{Some, None, Option};
+use option::Option;
+use option::Option::{Some, None};
 use os;
 use str::{FromStr, from_str, Str};
 use sync::atomic;
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs
new file mode 100644
index 00000000000..5e6dc6ec650
--- /dev/null
+++ b/src/libstd/sync/barrier.rs
@@ -0,0 +1,116 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use sync::{Mutex, Condvar};
+
+/// A barrier enables multiple tasks to synchronize the beginning
+/// of some computation.
+///
+/// ```rust
+/// use std::sync::{Arc, Barrier};
+///
+/// let barrier = Arc::new(Barrier::new(10));
+/// for _ in range(0u, 10) {
+///     let c = barrier.clone();
+///     // The same messages will be printed together.
+///     // You will NOT see any interleaving.
+///     spawn(proc() {
+///         println!("before wait");
+///         c.wait();
+///         println!("after wait");
+///     });
+/// }
+/// ```
+pub struct Barrier {
+    lock: Mutex<BarrierState>,
+    cvar: Condvar,
+    num_threads: uint,
+}
+
+// The inner state of a double barrier
+struct BarrierState {
+    count: uint,
+    generation_id: uint,
+}
+
+impl Barrier {
+    /// Create a new barrier that can block a given number of threads.
+    ///
+    /// A barrier will block `n`-1 threads which call `wait` and then wake up
+    /// all threads at once when the `n`th thread calls `wait`.
+    pub fn new(n: uint) -> Barrier {
+        Barrier {
+            lock: Mutex::new(BarrierState {
+                count: 0,
+                generation_id: 0,
+            }),
+            cvar: Condvar::new(),
+            num_threads: n,
+        }
+    }
+
+    /// Block the current thread until all threads has rendezvoused here.
+    ///
+    /// Barriers are re-usable after all threads have rendezvoused once, and can
+    /// be used continuously.
+    pub fn wait(&self) {
+        let mut lock = self.lock.lock();
+        let local_gen = lock.generation_id;
+        lock.count += 1;
+        if lock.count < self.num_threads {
+            // We need a while loop to guard against spurious wakeups.
+            // http://en.wikipedia.org/wiki/Spurious_wakeup
+            while local_gen == lock.generation_id &&
+                  lock.count < self.num_threads {
+                self.cvar.wait(&lock);
+            }
+        } else {
+            lock.count = 0;
+            lock.generation_id += 1;
+            self.cvar.notify_all();
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+
+    use sync::{Arc, Barrier};
+    use comm::Empty;
+
+    #[test]
+    fn test_barrier() {
+        let barrier = Arc::new(Barrier::new(10));
+        let (tx, rx) = channel();
+
+        for _ in range(0u, 9) {
+            let c = barrier.clone();
+            let tx = tx.clone();
+            spawn(proc() {
+                c.wait();
+                tx.send(true);
+            });
+        }
+
+        // At this point, all spawned tasks should be blocked,
+        // so we shouldn't get anything from the port
+        assert!(match rx.try_recv() {
+            Err(Empty) => true,
+            _ => false,
+        });
+
+        barrier.wait();
+        // Now, the barrier is cleared and we should get data.
+        for _ in range(0u, 9) {
+            rx.recv();
+        }
+    }
+}
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
new file mode 100644
index 00000000000..0fdd57b2792
--- /dev/null
+++ b/src/libstd/sync/condvar.rs
@@ -0,0 +1,365 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+
+use sync::atomic::{mod, AtomicUint};
+use sync::{mutex, StaticMutexGuard};
+use sys_common::condvar as sys;
+use sys_common::mutex as sys_mutex;
+use time::Duration;
+
+/// A Condition Variable
+///
+/// Condition variables represent the ability to block a thread such that it
+/// consumes no CPU time while waiting for an event to occur. Condition
+/// variables are typically associated with a boolean predicate (a condition)
+/// and a mutex. The predicate is always verified inside of the mutex before
+/// determining that thread must block.
+///
+/// Functions in this module will block the current **thread** of execution and
+/// are bindings to system-provided condition variables where possible. Note
+/// that this module places one additional restriction over the system condition
+/// variables: each condvar can be used with precisely one mutex at runtime. Any
+/// attempt to use multiple mutexes on the same condition variable will result
+/// in a runtime panic. If this is not desired, then the unsafe primitives in
+/// `sys` do not have this restriction but may result in undefined behavior.
+///
+/// # Example
+///
+/// ```
+/// use std::sync::{Arc, Mutex, Condvar};
+///
+/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
+/// let pair2 = pair.clone();
+///
+/// // Inside of our lock, spawn a new thread, and then wait for it to start
+/// spawn(proc() {
+///     let &(ref lock, ref cvar) = &*pair2;
+///     let mut started = lock.lock();
+///     *started = true;
+///     cvar.notify_one();
+/// });
+///
+/// // wait for the thread to start up
+/// let &(ref lock, ref cvar) = &*pair;
+/// let started = lock.lock();
+/// while !*started {
+///     cvar.wait(&started);
+/// }
+/// ```
+pub struct Condvar { inner: Box<StaticCondvar> }
+
+/// Statically allocated condition variables.
+///
+/// This structure is identical to `Condvar` except that it is suitable for use
+/// in static initializers for other structures.
+///
+/// # Example
+///
+/// ```
+/// use std::sync::{StaticCondvar, CONDVAR_INIT};
+///
+/// static CVAR: StaticCondvar = CONDVAR_INIT;
+/// ```
+pub struct StaticCondvar {
+    inner: sys::Condvar,
+    mutex: AtomicUint,
+}
+
+/// Constant initializer for a statically allocated condition variable.
+pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
+    inner: sys::CONDVAR_INIT,
+    mutex: atomic::INIT_ATOMIC_UINT,
+};
+
+/// A trait for vaules which can be passed to the waiting methods of condition
+/// variables. This is implemented by the mutex guards in this module.
+///
+/// Note that this trait should likely not be implemented manually unless you
+/// really know what you're doing.
+pub trait AsMutexGuard {
+    #[allow(missing_docs)]
+    unsafe fn as_mutex_guard(&self) -> &StaticMutexGuard;
+}
+
+impl Condvar {
+    /// Creates a new condition variable which is ready to be waited on and
+    /// notified.
+    pub fn new() -> Condvar {
+        Condvar {
+            inner: box StaticCondvar {
+                inner: unsafe { sys::Condvar::new() },
+                mutex: AtomicUint::new(0),
+            }
+        }
+    }
+
+    /// Block the current thread until this condition variable receives a
+    /// notification.
+    ///
+    /// This function will atomically unlock the mutex specified (represented by
+    /// `guard`) and block the current thread. This means that any calls to
+    /// `notify_*()` which happen logically after the mutex is unlocked are
+    /// candidates to wake this thread up. When this function call returns, the
+    /// lock specified will have been re-acquired.
+    ///
+    /// Note that this function is susceptible to spurious wakeups. Condition
+    /// variables normally have a boolean predicate associated with them, and
+    /// the predicate must always be checked each time this function returns to
+    /// protect against spurious wakeups.
+    ///
+    /// # Panics
+    ///
+    /// This function will `panic!()` if it is used with more than one mutex
+    /// over time. Each condition variable is dynamically bound to exactly one
+    /// mutex to ensure defined behavior across platforms. If this functionality
+    /// is not desired, then unsafe primitives in `sys` are provided.
+    pub fn wait<T: AsMutexGuard>(&self, mutex_guard: &T) {
+        unsafe {
+            let me: &'static Condvar = &*(self as *const _);
+            me.inner.wait(mutex_guard)
+        }
+    }
+
+    /// Wait on this condition variable for a notification, timing out after a
+    /// specified duration.
+    ///
+    /// The semantics of this function are equivalent to `wait()` except that
+    /// the thread will be blocked for roughly no longer than `dur`. This method
+    /// should not be used for precise timing due to anomalies such as
+    /// preemption or platform differences that may not cause the maximum amount
+    /// of time waited to be precisely `dur`.
+    ///
+    /// If the wait timed out, then `false` will be returned. Otherwise if a
+    /// notification was received then `true` will be returned.
+    ///
+    /// Like `wait`, the lock specified will be re-acquired when this function
+    /// returns, regardless of whether the timeout elapsed or not.
+    // Note that this method is *not* public, and this is quite intentional
+    // because we're not quite sure about the semantics of relative vs absolute
+    // durations or how the timing guarantees play into what the system APIs
+    // provide. There are also additional concerns about the unix-specific
+    // implementation which may need to be addressed.
+    #[allow(dead_code)]
+    fn wait_timeout<T: AsMutexGuard>(&self, mutex_guard: &T,
+                                     dur: Duration) -> bool {
+        unsafe {
+            let me: &'static Condvar = &*(self as *const _);
+            me.inner.wait_timeout(mutex_guard, dur)
+        }
+    }
+
+    /// Wake up one blocked thread on this condvar.
+    ///
+    /// If there is a blocked thread on this condition variable, then it will
+    /// be woken up from its call to `wait` or `wait_timeout`. Calls to
+    /// `notify_one` are not buffered in any way.
+    ///
+    /// To wake up all threads, see `notify_one()`.
+    pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
+
+    /// Wake up all blocked threads on this condvar.
+    ///
+    /// This method will ensure that any current waiters on the condition
+    /// variable are awoken. Calls to `notify_all()` are not buffered in any
+    /// way.
+    ///
+    /// To wake up only one thread, see `notify_one()`.
+    pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
+}
+
+impl Drop for Condvar {
+    fn drop(&mut self) {
+        unsafe { self.inner.inner.destroy() }
+    }
+}
+
+impl StaticCondvar {
+    /// Block the current thread until this condition variable receives a
+    /// notification.
+    ///
+    /// See `Condvar::wait`.
+    pub fn wait<T: AsMutexGuard>(&'static self, mutex_guard: &T) {
+        unsafe {
+            let lock = mutex_guard.as_mutex_guard();
+            let sys = mutex::guard_lock(lock);
+            self.verify(sys);
+            self.inner.wait(sys);
+            (*mutex::guard_poison(lock)).check("mutex");
+        }
+    }
+
+    /// Wait on this condition variable for a notification, timing out after a
+    /// specified duration.
+    ///
+    /// See `Condvar::wait_timeout`.
+    #[allow(dead_code)] // may want to stabilize this later, see wait_timeout above
+    fn wait_timeout<T: AsMutexGuard>(&'static self, mutex_guard: &T,
+                                     dur: Duration) -> bool {
+        unsafe {
+            let lock = mutex_guard.as_mutex_guard();
+            let sys = mutex::guard_lock(lock);
+            self.verify(sys);
+            let ret = self.inner.wait_timeout(sys, dur);
+            (*mutex::guard_poison(lock)).check("mutex");
+            return ret;
+        }
+    }
+
+    /// Wake up one blocked thread on this condvar.
+    ///
+    /// See `Condvar::notify_one`.
+    pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
+
+    /// Wake up all blocked threads on this condvar.
+    ///
+    /// See `Condvar::notify_all`.
+    pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
+
+    /// Deallocate all resources associated with this static condvar.
+    ///
+    /// This method is unsafe to call as there is no guarantee that there are no
+    /// active users of the condvar, and this also doesn't prevent any future
+    /// users of the condvar. This method is required to be called to not leak
+    /// memory on all platforms.
+    pub unsafe fn destroy(&'static self) {
+        self.inner.destroy()
+    }
+
+    fn verify(&self, mutex: &sys_mutex::Mutex) {
+        let addr = mutex as *const _ as uint;
+        match self.mutex.compare_and_swap(0, addr, atomic::SeqCst) {
+            // If we got out 0, then we have successfully bound the mutex to
+            // this cvar.
+            0 => {}
+
+            // If we get out a value that's the same as `addr`, then someone
+            // already beat us to the punch.
+            n if n == addr => {}
+
+            // Anything else and we're using more than one mutex on this cvar,
+            // which is currently disallowed.
+            _ => panic!("attempted to use a condition variable with two \
+                         mutexes"),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+
+    use time::Duration;
+    use super::{StaticCondvar, CONDVAR_INIT};
+    use sync::{StaticMutex, MUTEX_INIT, Condvar, Mutex, Arc};
+
+    #[test]
+    fn smoke() {
+        let c = Condvar::new();
+        c.notify_one();
+        c.notify_all();
+    }
+
+    #[test]
+    fn static_smoke() {
+        static C: StaticCondvar = CONDVAR_INIT;
+        C.notify_one();
+        C.notify_all();
+        unsafe { C.destroy(); }
+    }
+
+    #[test]
+    fn notify_one() {
+        static C: StaticCondvar = CONDVAR_INIT;
+        static M: StaticMutex = MUTEX_INIT;
+
+        let g = M.lock();
+        spawn(proc() {
+            let _g = M.lock();
+            C.notify_one();
+        });
+        C.wait(&g);
+        drop(g);
+        unsafe { C.destroy(); M.destroy(); }
+    }
+
+    #[test]
+    fn notify_all() {
+        const N: uint = 10;
+
+        let data = Arc::new((Mutex::new(0), Condvar::new()));
+        let (tx, rx) = channel();
+        for _ in range(0, N) {
+            let data = data.clone();
+            let tx = tx.clone();
+            spawn(proc() {
+                let &(ref lock, ref cond) = &*data;
+                let mut cnt = lock.lock();
+                *cnt += 1;
+                if *cnt == N {
+                    tx.send(());
+                }
+                while *cnt != 0 {
+                    cond.wait(&cnt);
+                }
+                tx.send(());
+            });
+        }
+        drop(tx);
+
+        let &(ref lock, ref cond) = &*data;
+        rx.recv();
+        let mut cnt = lock.lock();
+        *cnt = 0;
+        cond.notify_all();
+        drop(cnt);
+
+        for _ in range(0, N) {
+            rx.recv();
+        }
+    }
+
+    #[test]
+    fn wait_timeout() {
+        static C: StaticCondvar = CONDVAR_INIT;
+        static M: StaticMutex = MUTEX_INIT;
+
+        let g = M.lock();
+        assert!(!C.wait_timeout(&g, Duration::nanoseconds(1000)));
+        spawn(proc() {
+            let _g = M.lock();
+            C.notify_one();
+        });
+        assert!(C.wait_timeout(&g, Duration::days(1)));
+        drop(g);
+        unsafe { C.destroy(); M.destroy(); }
+    }
+
+    #[test]
+    #[should_fail]
+    fn two_mutexes() {
+        static M1: StaticMutex = MUTEX_INIT;
+        static M2: StaticMutex = MUTEX_INIT;
+        static C: StaticCondvar = CONDVAR_INIT;
+
+        let g = M1.lock();
+        spawn(proc() {
+            let _g = M1.lock();
+            C.notify_one();
+        });
+        C.wait(&g);
+        drop(g);
+
+        C.wait(&M2.lock());
+
+    }
+}
+
diff --git a/src/libstd/sync/deque.rs b/src/libstd/sync/deque.rs
deleted file mode 100644
index 33f6f77eb62..00000000000
--- a/src/libstd/sync/deque.rs
+++ /dev/null
@@ -1,663 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A (mostly) lock-free concurrent work-stealing deque
-//!
-//! This module contains an implementation of the Chase-Lev work stealing deque
-//! described in "Dynamic Circular Work-Stealing Deque". The implementation is
-//! heavily based on the pseudocode found in the paper.
-//!
-//! This implementation does not want to have the restriction of a garbage
-//! collector for reclamation of buffers, and instead it uses a shared pool of
-//! buffers. This shared pool is required for correctness in this
-//! implementation.
-//!
-//! The only lock-synchronized portions of this deque are the buffer allocation
-//! and deallocation portions. Otherwise all operations are lock-free.
-//!
-//! # Example
-//!
-//!     use std::sync::deque::BufferPool;
-//!
-//!     let mut pool = BufferPool::new();
-//!     let (mut worker, mut stealer) = pool.deque();
-//!
-//!     // Only the worker may push/pop
-//!     worker.push(1i);
-//!     worker.pop();
-//!
-//!     // Stealers take data from the other end of the deque
-//!     worker.push(1i);
-//!     stealer.steal();
-//!
-//!     // Stealers can be cloned to have many stealers stealing in parallel
-//!     worker.push(1i);
-//!     let mut stealer2 = stealer.clone();
-//!     stealer2.steal();
-
-#![experimental]
-
-// NB: the "buffer pool" strategy is not done for speed, but rather for
-//     correctness. For more info, see the comment on `swap_buffer`
-
-// FIXME: all atomic operations in this module use a SeqCst ordering. That is
-//      probably overkill
-
-pub use self::Stolen::*;
-
-use core::prelude::*;
-
-use alloc::arc::Arc;
-use alloc::heap::{allocate, deallocate};
-use alloc::boxed::Box;
-use vec::Vec;
-use core::kinds::marker;
-use core::mem::{forget, min_align_of, size_of, transmute};
-use core::ptr;
-use rustrt::exclusive::Exclusive;
-
-use sync::atomic::{AtomicInt, AtomicPtr, SeqCst};
-
-// Once the queue is less than 1/K full, then it will be downsized. Note that
-// the deque requires that this number be less than 2.
-static K: int = 4;
-
-// Minimum number of bits that a buffer size should be. No buffer will resize to
-// under this value, and all deques will initially contain a buffer of this
-// size.
-//
-// The size in question is 1 << MIN_BITS
-static MIN_BITS: uint = 7;
-
-struct Deque<T> {
-    bottom: AtomicInt,
-    top: AtomicInt,
-    array: AtomicPtr<Buffer<T>>,
-    pool: BufferPool<T>,
-}
-
-/// Worker half of the work-stealing deque. This worker has exclusive access to
-/// one side of the deque, and uses `push` and `pop` method to manipulate it.
-///
-/// There may only be one worker per deque.
-pub struct Worker<T> {
-    deque: Arc<Deque<T>>,
-    _noshare: marker::NoSync,
-}
-
-/// The stealing half of the work-stealing deque. Stealers have access to the
-/// opposite end of the deque from the worker, and they only have access to the
-/// `steal` method.
-pub struct Stealer<T> {
-    deque: Arc<Deque<T>>,
-    _noshare: marker::NoSync,
-}
-
-/// When stealing some data, this is an enumeration of the possible outcomes.
-#[deriving(PartialEq, Show)]
-pub enum Stolen<T> {
-    /// The deque was empty at the time of stealing
-    Empty,
-    /// The stealer lost the race for stealing data, and a retry may return more
-    /// data.
-    Abort,
-    /// The stealer has successfully stolen some data.
-    Data(T),
-}
-
-/// The allocation pool for buffers used by work-stealing deques. Right now this
-/// structure is used for reclamation of memory after it is no longer in use by
-/// deques.
-///
-/// This data structure is protected by a mutex, but it is rarely used. Deques
-/// will only use this structure when allocating a new buffer or deallocating a
-/// previous one.
-pub struct BufferPool<T> {
-    pool: Arc<Exclusive<Vec<Box<Buffer<T>>>>>,
-}
-
-/// An internal buffer used by the chase-lev deque. This structure is actually
-/// implemented as a circular buffer, and is used as the intermediate storage of
-/// the data in the deque.
-///
-/// This type is implemented with *T instead of Vec<T> for two reasons:
-///
-///   1. There is nothing safe about using this buffer. This easily allows the
-///      same value to be read twice in to rust, and there is nothing to
-///      prevent this. The usage by the deque must ensure that one of the
-///      values is forgotten. Furthermore, we only ever want to manually run
-///      destructors for values in this buffer (on drop) because the bounds
-///      are defined by the deque it's owned by.
-///
-///   2. We can certainly avoid bounds checks using *T instead of Vec<T>, although
-///      LLVM is probably pretty good at doing this already.
-struct Buffer<T> {
-    storage: *const T,
-    log_size: uint,
-}
-
-impl<T: Send> BufferPool<T> {
-    /// Allocates a new buffer pool which in turn can be used to allocate new
-    /// deques.
-    pub fn new() -> BufferPool<T> {
-        BufferPool { pool: Arc::new(Exclusive::new(Vec::new())) }
-    }
-
-    /// Allocates a new work-stealing deque which will send/receiving memory to
-    /// and from this buffer pool.
-    pub fn deque(&self) -> (Worker<T>, Stealer<T>) {
-        let a = Arc::new(Deque::new(self.clone()));
-        let b = a.clone();
-        (Worker { deque: a, _noshare: marker::NoSync },
-         Stealer { deque: b, _noshare: marker::NoSync })
-    }
-
-    fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> {
-        unsafe {
-            let mut pool = self.pool.lock();
-            match pool.iter().position(|x| x.size() >= (1 << bits)) {
-                Some(i) => pool.remove(i).unwrap(),
-                None => box Buffer::new(bits)
-            }
-        }
-    }
-
-    fn free(&self, buf: Box<Buffer<T>>) {
-        unsafe {
-            let mut pool = self.pool.lock();
-            match pool.iter().position(|v| v.size() > buf.size()) {
-                Some(i) => pool.insert(i, buf),
-                None => pool.push(buf),
-            }
-        }
-    }
-}
-
-impl<T: Send> Clone for BufferPool<T> {
-    fn clone(&self) -> BufferPool<T> { BufferPool { pool: self.pool.clone() } }
-}
-
-impl<T: Send> Worker<T> {
-    /// Pushes data onto the front of this work queue.
-    pub fn push(&self, t: T) {
-        unsafe { self.deque.push(t) }
-    }
-    /// Pops data off the front of the work queue, returning `None` on an empty
-    /// queue.
-    pub fn pop(&self) -> Option<T> {
-        unsafe { self.deque.pop() }
-    }
-
-    /// Gets access to the buffer pool that this worker is attached to. This can
-    /// be used to create more deques which share the same buffer pool as this
-    /// deque.
-    pub fn pool<'a>(&'a self) -> &'a BufferPool<T> {
-        &self.deque.pool
-    }
-}
-
-impl<T: Send> Stealer<T> {
-    /// Steals work off the end of the queue (opposite of the worker's end)
-    pub fn steal(&self) -> Stolen<T> {
-        unsafe { self.deque.steal() }
-    }
-
-    /// Gets access to the buffer pool that this stealer is attached to. This
-    /// can be used to create more deques which share the same buffer pool as
-    /// this deque.
-    pub fn pool<'a>(&'a self) -> &'a BufferPool<T> {
-        &self.deque.pool
-    }
-}
-
-impl<T: Send> Clone for Stealer<T> {
-    fn clone(&self) -> Stealer<T> {
-        Stealer { deque: self.deque.clone(), _noshare: marker::NoSync }
-    }
-}
-
-// Almost all of this code can be found directly in the paper so I'm not
-// personally going to heavily comment what's going on here.
-
-impl<T: Send> Deque<T> {
-    fn new(mut pool: BufferPool<T>) -> Deque<T> {
-        let buf = pool.alloc(MIN_BITS);
-        Deque {
-            bottom: AtomicInt::new(0),
-            top: AtomicInt::new(0),
-            array: AtomicPtr::new(unsafe { transmute(buf) }),
-            pool: pool,
-        }
-    }
-
-    unsafe fn push(&self, data: T) {
-        let mut b = self.bottom.load(SeqCst);
-        let t = self.top.load(SeqCst);
-        let mut a = self.array.load(SeqCst);
-        let size = b - t;
-        if size >= (*a).size() - 1 {
-            // You won't find this code in the chase-lev deque paper. This is
-            // alluded to in a small footnote, however. We always free a buffer
-            // when growing in order to prevent leaks.
-            a = self.swap_buffer(b, a, (*a).resize(b, t, 1));
-            b = self.bottom.load(SeqCst);
-        }
-        (*a).put(b, data);
-        self.bottom.store(b + 1, SeqCst);
-    }
-
-    unsafe fn pop(&self) -> Option<T> {
-        let b = self.bottom.load(SeqCst);
-        let a = self.array.load(SeqCst);
-        let b = b - 1;
-        self.bottom.store(b, SeqCst);
-        let t = self.top.load(SeqCst);
-        let size = b - t;
-        if size < 0 {
-            self.bottom.store(t, SeqCst);
-            return None;
-        }
-        let data = (*a).get(b);
-        if size > 0 {
-            self.maybe_shrink(b, t);
-            return Some(data);
-        }
-        if self.top.compare_and_swap(t, t + 1, SeqCst) == t {
-            self.bottom.store(t + 1, SeqCst);
-            return Some(data);
-        } else {
-            self.bottom.store(t + 1, SeqCst);
-            forget(data); // someone else stole this value
-            return None;
-        }
-    }
-
-    unsafe fn steal(&self) -> Stolen<T> {
-        let t = self.top.load(SeqCst);
-        let old = self.array.load(SeqCst);
-        let b = self.bottom.load(SeqCst);
-        let a = self.array.load(SeqCst);
-        let size = b - t;
-        if size <= 0 { return Empty }
-        if size % (*a).size() == 0 {
-            if a == old && t == self.top.load(SeqCst) {
-                return Empty
-            }
-            return Abort
-        }
-        let data = (*a).get(t);
-        if self.top.compare_and_swap(t, t + 1, SeqCst) == t {
-            Data(data)
-        } else {
-            forget(data); // someone else stole this value
-            Abort
-        }
-    }
-
-    unsafe fn maybe_shrink(&self, b: int, t: int) {
-        let a = self.array.load(SeqCst);
-        if b - t < (*a).size() / K && b - t > (1 << MIN_BITS) {
-            self.swap_buffer(b, a, (*a).resize(b, t, -1));
-        }
-    }
-
-    // Helper routine not mentioned in the paper which is used in growing and
-    // shrinking buffers to swap in a new buffer into place. As a bit of a
-    // recap, the whole point that we need a buffer pool rather than just
-    // calling malloc/free directly is that stealers can continue using buffers
-    // after this method has called 'free' on it. The continued usage is simply
-    // a read followed by a forget, but we must make sure that the memory can
-    // continue to be read after we flag this buffer for reclamation.
-    unsafe fn swap_buffer(&self, b: int, old: *mut Buffer<T>,
-                          buf: Buffer<T>) -> *mut Buffer<T> {
-        let newbuf: *mut Buffer<T> = transmute(box buf);
-        self.array.store(newbuf, SeqCst);
-        let ss = (*newbuf).size();
-        self.bottom.store(b + ss, SeqCst);
-        let t = self.top.load(SeqCst);
-        if self.top.compare_and_swap(t, t + ss, SeqCst) != t {
-            self.bottom.store(b, SeqCst);
-        }
-        self.pool.free(transmute(old));
-        return newbuf;
-    }
-}
-
-
-#[unsafe_destructor]
-impl<T: Send> Drop for Deque<T> {
-    fn drop(&mut self) {
-        let t = self.top.load(SeqCst);
-        let b = self.bottom.load(SeqCst);
-        let a = self.array.load(SeqCst);
-        // Free whatever is leftover in the dequeue, and then move the buffer
-        // back into the pool.
-        for i in range(t, b) {
-            let _: T = unsafe { (*a).get(i) };
-        }
-        self.pool.free(unsafe { transmute(a) });
-    }
-}
-
-#[inline]
-fn buffer_alloc_size<T>(log_size: uint) -> uint {
-    (1 << log_size) * size_of::<T>()
-}
-
-impl<T: Send> Buffer<T> {
-    unsafe fn new(log_size: uint) -> Buffer<T> {
-        let size = buffer_alloc_size::<T>(log_size);
-        let buffer = allocate(size, min_align_of::<T>());
-        if buffer.is_null() { ::alloc::oom() }
-        Buffer {
-            storage: buffer as *const T,
-            log_size: log_size,
-        }
-    }
-
-    fn size(&self) -> int { 1 << self.log_size }
-
-    // Apparently LLVM cannot optimize (foo % (1 << bar)) into this implicitly
-    fn mask(&self) -> int { (1 << self.log_size) - 1 }
-
-    unsafe fn elem(&self, i: int) -> *const T {
-        self.storage.offset(i & self.mask())
-    }
-
-    // This does not protect against loading duplicate values of the same cell,
-    // nor does this clear out the contents contained within. Hence, this is a
-    // very unsafe method which the caller needs to treat specially in case a
-    // race is lost.
-    unsafe fn get(&self, i: int) -> T {
-        ptr::read(self.elem(i))
-    }
-
-    // Unsafe because this unsafely overwrites possibly uninitialized or
-    // initialized data.
-    unsafe fn put(&self, i: int, t: T) {
-        ptr::write(self.elem(i) as *mut T, t);
-    }
-
-    // Again, unsafe because this has incredibly dubious ownership violations.
-    // It is assumed that this buffer is immediately dropped.
-    unsafe fn resize(&self, b: int, t: int, delta: int) -> Buffer<T> {
-        // NB: not entirely obvious, but thanks to 2's complement,
-        // casting delta to uint and then adding gives the desired
-        // effect.
-        let buf = Buffer::new(self.log_size + delta as uint);
-        for i in range(t, b) {
-            buf.put(i, self.get(i));
-        }
-        return buf;
-    }
-}
-
-#[unsafe_destructor]
-impl<T: Send> Drop for Buffer<T> {
-    fn drop(&mut self) {
-        // It is assumed that all buffers are empty on drop.
-        let size = buffer_alloc_size::<T>(self.log_size);
-        unsafe { deallocate(self.storage as *mut u8, size, min_align_of::<T>()) }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use super::{Data, BufferPool, Abort, Empty, Worker, Stealer};
-
-    use mem;
-    use rustrt::thread::Thread;
-    use rand;
-    use rand::Rng;
-    use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst,
-                       AtomicUint, INIT_ATOMIC_UINT};
-    use vec;
-
-    #[test]
-    fn smoke() {
-        let pool = BufferPool::new();
-        let (w, s) = pool.deque();
-        assert_eq!(w.pop(), None);
-        assert_eq!(s.steal(), Empty);
-        w.push(1i);
-        assert_eq!(w.pop(), Some(1));
-        w.push(1);
-        assert_eq!(s.steal(), Data(1));
-        w.push(1);
-        assert_eq!(s.clone().steal(), Data(1));
-    }
-
-    #[test]
-    fn stealpush() {
-        static AMT: int = 100000;
-        let pool = BufferPool::<int>::new();
-        let (w, s) = pool.deque();
-        let t = Thread::start(proc() {
-            let mut left = AMT;
-            while left > 0 {
-                match s.steal() {
-                    Data(i) => {
-                        assert_eq!(i, 1);
-                        left -= 1;
-                    }
-                    Abort | Empty => {}
-                }
-            }
-        });
-
-        for _ in range(0, AMT) {
-            w.push(1);
-        }
-
-        t.join();
-    }
-
-    #[test]
-    fn stealpush_large() {
-        static AMT: int = 100000;
-        let pool = BufferPool::<(int, int)>::new();
-        let (w, s) = pool.deque();
-        let t = Thread::start(proc() {
-            let mut left = AMT;
-            while left > 0 {
-                match s.steal() {
-                    Data((1, 10)) => { left -= 1; }
-                    Data(..) => panic!(),
-                    Abort | Empty => {}
-                }
-            }
-        });
-
-        for _ in range(0, AMT) {
-            w.push((1, 10));
-        }
-
-        t.join();
-    }
-
-    fn stampede(w: Worker<Box<int>>, s: Stealer<Box<int>>,
-                nthreads: int, amt: uint) {
-        for _ in range(0, amt) {
-            w.push(box 20);
-        }
-        let mut remaining = AtomicUint::new(amt);
-        let unsafe_remaining: *mut AtomicUint = &mut remaining;
-
-        let threads = range(0, nthreads).map(|_| {
-            let s = s.clone();
-            Thread::start(proc() {
-                unsafe {
-                    while (*unsafe_remaining).load(SeqCst) > 0 {
-                        match s.steal() {
-                            Data(box 20) => {
-                                (*unsafe_remaining).fetch_sub(1, SeqCst);
-                            }
-                            Data(..) => panic!(),
-                            Abort | Empty => {}
-                        }
-                    }
-                }
-            })
-        }).collect::<Vec<Thread<()>>>();
-
-        while remaining.load(SeqCst) > 0 {
-            match w.pop() {
-                Some(box 20) => { remaining.fetch_sub(1, SeqCst); }
-                Some(..) => panic!(),
-                None => {}
-            }
-        }
-
-        for thread in threads.into_iter() {
-            thread.join();
-        }
-    }
-
-    #[test]
-    fn run_stampede() {
-        let pool = BufferPool::<Box<int>>::new();
-        let (w, s) = pool.deque();
-        stampede(w, s, 8, 10000);
-    }
-
-    #[test]
-    fn many_stampede() {
-        static AMT: uint = 4;
-        let pool = BufferPool::<Box<int>>::new();
-        let threads = range(0, AMT).map(|_| {
-            let (w, s) = pool.deque();
-            Thread::start(proc() {
-                stampede(w, s, 4, 10000);
-            })
-        }).collect::<Vec<Thread<()>>>();
-
-        for thread in threads.into_iter() {
-            thread.join();
-        }
-    }
-
-    #[test]
-    fn stress() {
-        static AMT: int = 100000;
-        static NTHREADS: int = 8;
-        static DONE: AtomicBool = INIT_ATOMIC_BOOL;
-        static HITS: AtomicUint = INIT_ATOMIC_UINT;
-        let pool = BufferPool::<int>::new();
-        let (w, s) = pool.deque();
-
-        let threads = range(0, NTHREADS).map(|_| {
-            let s = s.clone();
-            Thread::start(proc() {
-                loop {
-                    match s.steal() {
-                        Data(2) => { HITS.fetch_add(1, SeqCst); }
-                        Data(..) => panic!(),
-                        _ if DONE.load(SeqCst) => break,
-                        _ => {}
-                    }
-                }
-            })
-        }).collect::<Vec<Thread<()>>>();
-
-        let mut rng = rand::task_rng();
-        let mut expected = 0;
-        while expected < AMT {
-            if rng.gen_range(0i, 3) == 2 {
-                match w.pop() {
-                    None => {}
-                    Some(2) => { HITS.fetch_add(1, SeqCst); },
-                    Some(_) => panic!(),
-                }
-            } else {
-                expected += 1;
-                w.push(2);
-            }
-        }
-
-        while HITS.load(SeqCst) < AMT as uint {
-            match w.pop() {
-                None => {}
-                Some(2) => { HITS.fetch_add(1, SeqCst); },
-                Some(_) => panic!(),
-            }
-        }
-        DONE.store(true, SeqCst);
-
-        for thread in threads.into_iter() {
-            thread.join();
-        }
-
-        assert_eq!(HITS.load(SeqCst), expected as uint);
-    }
-
-    #[test]
-    #[cfg_attr(windows, ignore)] // apparently windows scheduling is weird?
-    fn no_starvation() {
-        static AMT: int = 10000;
-        static NTHREADS: int = 4;
-        static DONE: AtomicBool = INIT_ATOMIC_BOOL;
-        let pool = BufferPool::<(int, uint)>::new();
-        let (w, s) = pool.deque();
-
-        let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| {
-            let s = s.clone();
-            let unique_box = box AtomicUint::new(0);
-            let thread_box = unsafe {
-                *mem::transmute::<&Box<AtomicUint>,
-                                  *const *mut AtomicUint>(&unique_box)
-            };
-            (Thread::start(proc() {
-                unsafe {
-                    loop {
-                        match s.steal() {
-                            Data((1, 2)) => {
-                                (*thread_box).fetch_add(1, SeqCst);
-                            }
-                            Data(..) => panic!(),
-                            _ if DONE.load(SeqCst) => break,
-                            _ => {}
-                        }
-                    }
-                }
-            }), unique_box)
-        }));
-
-        let mut rng = rand::task_rng();
-        let mut myhit = false;
-        'outer: loop {
-            for _ in range(0, rng.gen_range(0, AMT)) {
-                if !myhit && rng.gen_range(0i, 3) == 2 {
-                    match w.pop() {
-                        None => {}
-                        Some((1, 2)) => myhit = true,
-                        Some(_) => panic!(),
-                    }
-                } else {
-                    w.push((1, 2));
-                }
-            }
-
-            for slot in hits.iter() {
-                let amt = slot.load(SeqCst);
-                if amt == 0 { continue 'outer; }
-            }
-            if myhit {
-                break
-            }
-        }
-
-        DONE.store(true, SeqCst);
-
-        for thread in threads.into_iter() {
-            thread.join();
-        }
-    }
-}
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index f2f9351fd0d..79e0d487cad 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -148,7 +148,7 @@ mod test {
     use prelude::*;
     use sync::Future;
     use task;
-    use comm::{channel, Sender};
+    use comm::channel;
 
     #[test]
     fn test_from_value() {
diff --git a/src/libstd/sync/lock.rs b/src/libstd/sync/lock.rs
deleted file mode 100644
index 77f5b013519..00000000000
--- a/src/libstd/sync/lock.rs
+++ /dev/null
@@ -1,805 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Wrappers for safe, shared, mutable memory between tasks
-//!
-//! The wrappers in this module build on the primitives from `sync::raw` to
-//! provide safe interfaces around using the primitive locks. These primitives
-//! implement a technique called "poisoning" where when a task panicked with a
-//! held lock, all future attempts to use the lock will panic.
-//!
-//! For example, if two tasks are contending on a mutex and one of them panics
-//! after grabbing the lock, the second task will immediately panic because the
-//! lock is now poisoned.
-
-use core::prelude::*;
-
-use self::Inner::*;
-
-use core::cell::UnsafeCell;
-use rustrt::local::Local;
-use rustrt::task::Task;
-
-use super::raw;
-
-// Poisoning helpers
-
-struct PoisonOnFail<'a> {
-    flag: &'a mut bool,
-    failed: bool,
-}
-
-fn failing() -> bool {
-    Local::borrow(None::<Task>).unwinder.unwinding()
-}
-
-impl<'a> PoisonOnFail<'a> {
-    fn check(flag: bool, name: &str) {
-        if flag {
-            panic!("Poisoned {} - another task failed inside!", name);
-        }
-    }
-
-    fn new<'a>(flag: &'a mut bool, name: &str) -> PoisonOnFail<'a> {
-        PoisonOnFail::check(*flag, name);
-        PoisonOnFail {
-            flag: flag,
-            failed: failing()
-        }
-    }
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for PoisonOnFail<'a> {
-    fn drop(&mut self) {
-        if !self.failed && failing() {
-            *self.flag = true;
-        }
-    }
-}
-
-// Condvar
-
-enum Inner<'a> {
-    InnerMutex(raw::MutexGuard<'a>),
-    InnerRWLock(raw::RWLockWriteGuard<'a>),
-}
-
-impl<'b> Inner<'b> {
-    fn cond<'a>(&'a self) -> &'a raw::Condvar<'b> {
-        match *self {
-            InnerMutex(ref m) => &m.cond,
-            InnerRWLock(ref m) => &m.cond,
-        }
-    }
-}
-
-/// A condition variable, a mechanism for unlock-and-descheduling and
-/// signaling, for use with the lock types.
-pub struct Condvar<'a> {
-    name: &'static str,
-    // n.b. Inner must be after PoisonOnFail because we must set the poison flag
-    //      *inside* the mutex, and struct fields are destroyed top-to-bottom
-    //      (destroy the lock guard last).
-    poison: PoisonOnFail<'a>,
-    inner: Inner<'a>,
-}
-
-impl<'a> Condvar<'a> {
-    /// Atomically exit the associated lock and block until a signal is sent.
-    ///
-    /// wait() is equivalent to wait_on(0).
-    ///
-    /// # Panics
-    ///
-    /// A task which is killed while waiting on a condition variable will wake
-    /// up, panic, and unlock the associated lock as it unwinds.
-    #[inline]
-    pub fn wait(&self) { self.wait_on(0) }
-
-    /// Atomically exit the associated lock and block on a specified condvar
-    /// until a signal is sent on that same condvar.
-    ///
-    /// The associated lock must have been initialised with an appropriate
-    /// number of condvars. The condvar_id must be between 0 and num_condvars-1
-    /// or else this call will fail.
-    #[inline]
-    pub fn wait_on(&self, condvar_id: uint) {
-        assert!(!*self.poison.flag);
-        self.inner.cond().wait_on(condvar_id);
-        // This is why we need to wrap sync::condvar.
-        PoisonOnFail::check(*self.poison.flag, self.name);
-    }
-
-    /// Wake up a blocked task. Returns false if there was no blocked task.
-    #[inline]
-    pub fn signal(&self) -> bool { self.signal_on(0) }
-
-    /// Wake up a blocked task on a specified condvar (as
-    /// sync::cond.signal_on). Returns false if there was no blocked task.
-    #[inline]
-    pub fn signal_on(&self, condvar_id: uint) -> bool {
-        assert!(!*self.poison.flag);
-        self.inner.cond().signal_on(condvar_id)
-    }
-
-    /// Wake up all blocked tasks. Returns the number of tasks woken.
-    #[inline]
-    pub fn broadcast(&self) -> uint { self.broadcast_on(0) }
-
-    /// Wake up all blocked tasks on a specified condvar (as
-    /// sync::cond.broadcast_on). Returns the number of tasks woken.
-    #[inline]
-    pub fn broadcast_on(&self, condvar_id: uint) -> uint {
-        assert!(!*self.poison.flag);
-        self.inner.cond().broadcast_on(condvar_id)
-    }
-}
-
-/// A wrapper type which provides synchronized access to the underlying data, of
-/// type `T`. A mutex always provides exclusive access, and concurrent requests
-/// will block while the mutex is already locked.
-///
-/// # Example
-///
-/// ```
-/// use std::sync::{Mutex, Arc};
-///
-/// let mutex = Arc::new(Mutex::new(1i));
-/// let mutex2 = mutex.clone();
-///
-/// spawn(proc() {
-///     let mut val = mutex2.lock();
-///     *val += 1;
-///     val.cond.signal();
-/// });
-///
-/// let value = mutex.lock();
-/// while *value != 2 {
-///     value.cond.wait();
-/// }
-/// ```
-pub struct Mutex<T> {
-    lock: raw::Mutex,
-    failed: UnsafeCell<bool>,
-    data: UnsafeCell<T>,
-}
-
-/// An guard which is created by locking a mutex. Through this guard the
-/// underlying data can be accessed.
-pub struct MutexGuard<'a, T:'a> {
-    // FIXME #12808: strange name to try to avoid interfering with
-    // field accesses of the contained type via Deref
-    _data: &'a mut T,
-    /// Inner condition variable connected to the locked mutex that this guard
-    /// was created from. This can be used for atomic-unlock-and-deschedule.
-    pub cond: Condvar<'a>,
-}
-
-impl<T: Send> Mutex<T> {
-    /// Creates a new mutex to protect the user-supplied data.
-    pub fn new(user_data: T) -> Mutex<T> {
-        Mutex::new_with_condvars(user_data, 1)
-    }
-
-    /// Create a new mutex, with a specified number of associated condvars.
-    ///
-    /// This will allow calling wait_on/signal_on/broadcast_on with condvar IDs
-    /// between 0 and num_condvars-1. (If num_condvars is 0, lock_cond will be
-    /// allowed but any operations on the condvar will fail.)
-    pub fn new_with_condvars(user_data: T, num_condvars: uint) -> Mutex<T> {
-        Mutex {
-            lock: raw::Mutex::new_with_condvars(num_condvars),
-            failed: UnsafeCell::new(false),
-            data: UnsafeCell::new(user_data),
-        }
-    }
-
-    /// Access the underlying mutable data with mutual exclusion from other
-    /// tasks. The returned value is an RAII guard which will unlock the mutex
-    /// when dropped. All concurrent tasks attempting to lock the mutex will
-    /// block while the returned value is still alive.
-    ///
-    /// # Panics
-    ///
-    /// Panicking while inside the Mutex will unlock the Mutex while unwinding, so
-    /// that other tasks won't block forever. It will also poison the Mutex:
-    /// any tasks that subsequently try to access it (including those already
-    /// blocked on the mutex) will also panic immediately.
-    #[inline]
-    pub fn lock<'a>(&'a self) -> MutexGuard<'a, T> {
-        let guard = self.lock.lock();
-
-        // These two accesses are safe because we're guaranteed at this point
-        // that we have exclusive access to this mutex. We are indeed able to
-        // promote ourselves from &Mutex to `&mut T`
-        let poison = unsafe { &mut *self.failed.get() };
-        let data = unsafe { &mut *self.data.get() };
-
-        MutexGuard {
-            _data: data,
-            cond: Condvar {
-                name: "Mutex",
-                poison: PoisonOnFail::new(poison, "Mutex"),
-                inner: InnerMutex(guard),
-            },
-        }
-    }
-}
-
-impl<'a, T: Send> Deref<T> for MutexGuard<'a, T> {
-    fn deref<'a>(&'a self) -> &'a T { &*self._data }
-}
-impl<'a, T: Send> DerefMut<T> for MutexGuard<'a, T> {
-    fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
-}
-
-/// A dual-mode reader-writer lock. The data can be accessed mutably or
-/// immutably, and immutably-accessing tasks may run concurrently.
-///
-/// # Example
-///
-/// ```
-/// use std::sync::{RWLock, Arc};
-///
-/// let lock1 = Arc::new(RWLock::new(1i));
-/// let lock2 = lock1.clone();
-///
-/// spawn(proc() {
-///     let mut val = lock2.write();
-///     *val = 3;
-///     let val = val.downgrade();
-///     println!("{}", *val);
-/// });
-///
-/// let val = lock1.read();
-/// println!("{}", *val);
-/// ```
-pub struct RWLock<T> {
-    lock: raw::RWLock,
-    failed: UnsafeCell<bool>,
-    data: UnsafeCell<T>,
-}
-
-/// A guard which is created by locking an rwlock in write mode. Through this
-/// guard the underlying data can be accessed.
-pub struct RWLockWriteGuard<'a, T:'a> {
-    // FIXME #12808: strange name to try to avoid interfering with
-    // field accesses of the contained type via Deref
-    _data: &'a mut T,
-    /// Inner condition variable that can be used to sleep on the write mode of
-    /// this rwlock.
-    pub cond: Condvar<'a>,
-}
-
-/// A guard which is created by locking an rwlock in read mode. Through this
-/// guard the underlying data can be accessed.
-pub struct RWLockReadGuard<'a, T:'a> {
-    // FIXME #12808: strange names to try to avoid interfering with
-    // field accesses of the contained type via Deref
-    _data: &'a T,
-    _guard: raw::RWLockReadGuard<'a>,
-}
-
-impl<T: Send + Sync> RWLock<T> {
-    /// Create a reader/writer lock with the supplied data.
-    pub fn new(user_data: T) -> RWLock<T> {
-        RWLock::new_with_condvars(user_data, 1)
-    }
-
-    /// Create a reader/writer lock with the supplied data and a specified number
-    /// of condvars (as sync::RWLock::new_with_condvars).
-    pub fn new_with_condvars(user_data: T, num_condvars: uint) -> RWLock<T> {
-        RWLock {
-            lock: raw::RWLock::new_with_condvars(num_condvars),
-            failed: UnsafeCell::new(false),
-            data: UnsafeCell::new(user_data),
-        }
-    }
-
-    /// Access the underlying data mutably. Locks the rwlock in write mode;
-    /// other readers and writers will block.
-    ///
-    /// # Panics
-    ///
-    /// Panicking while inside the lock will unlock the lock while unwinding, so
-    /// that other tasks won't block forever. As Mutex.lock, it will also poison
-    /// the lock, so subsequent readers and writers will both also panic.
-    #[inline]
-    pub fn write<'a>(&'a self) -> RWLockWriteGuard<'a, T> {
-        let guard = self.lock.write();
-
-        // These two accesses are safe because we're guaranteed at this point
-        // that we have exclusive access to this rwlock. We are indeed able to
-        // promote ourselves from &RWLock to `&mut T`
-        let poison = unsafe { &mut *self.failed.get() };
-        let data = unsafe { &mut *self.data.get() };
-
-        RWLockWriteGuard {
-            _data: data,
-            cond: Condvar {
-                name: "RWLock",
-                poison: PoisonOnFail::new(poison, "RWLock"),
-                inner: InnerRWLock(guard),
-            },
-        }
-    }
-
-    /// Access the underlying data immutably. May run concurrently with other
-    /// reading tasks.
-    ///
-    /// # Panics
-    ///
-    /// Panicking will unlock the lock while unwinding. However, unlike all other
-    /// access modes, this will not poison the lock.
-    pub fn read<'a>(&'a self) -> RWLockReadGuard<'a, T> {
-        let guard = self.lock.read();
-        PoisonOnFail::check(unsafe { *self.failed.get() }, "RWLock");
-        RWLockReadGuard {
-            _guard: guard,
-            _data: unsafe { &*self.data.get() },
-        }
-    }
-}
-
-impl<'a, T: Send + Sync> RWLockWriteGuard<'a, T> {
-    /// Consumes this write lock token, returning a new read lock token.
-    ///
-    /// This will allow pending readers to come into the lock.
-    pub fn downgrade(self) -> RWLockReadGuard<'a, T> {
-        let RWLockWriteGuard { _data, cond } = self;
-        // convert the data to read-only explicitly
-        let data = &*_data;
-        let guard = match cond.inner {
-            InnerMutex(..) => unreachable!(),
-            InnerRWLock(guard) => guard.downgrade()
-        };
-        RWLockReadGuard { _guard: guard, _data: data }
-    }
-}
-
-impl<'a, T: Send + Sync> Deref<T> for RWLockReadGuard<'a, T> {
-    fn deref<'a>(&'a self) -> &'a T { self._data }
-}
-impl<'a, T: Send + Sync> Deref<T> for RWLockWriteGuard<'a, T> {
-    fn deref<'a>(&'a self) -> &'a T { &*self._data }
-}
-impl<'a, T: Send + Sync> DerefMut<T> for RWLockWriteGuard<'a, T> {
-    fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
-}
-
-/// A barrier enables multiple tasks to synchronize the beginning
-/// of some computation.
-///
-/// ```rust
-/// use std::sync::{Arc, Barrier};
-///
-/// let barrier = Arc::new(Barrier::new(10));
-/// for _ in range(0u, 10) {
-///     let c = barrier.clone();
-///     // The same messages will be printed together.
-///     // You will NOT see any interleaving.
-///     spawn(proc() {
-///         println!("before wait");
-///         c.wait();
-///         println!("after wait");
-///     });
-/// }
-/// ```
-pub struct Barrier {
-    lock: Mutex<BarrierState>,
-    num_tasks: uint,
-}
-
-// The inner state of a double barrier
-struct BarrierState {
-    count: uint,
-    generation_id: uint,
-}
-
-impl Barrier {
-    /// Create a new barrier that can block a given number of tasks.
-    pub fn new(num_tasks: uint) -> Barrier {
-        Barrier {
-            lock: Mutex::new(BarrierState {
-                count: 0,
-                generation_id: 0,
-            }),
-            num_tasks: num_tasks,
-        }
-    }
-
-    /// Block the current task until a certain number of tasks is waiting.
-    pub fn wait(&self) {
-        let mut lock = self.lock.lock();
-        let local_gen = lock.generation_id;
-        lock.count += 1;
-        if lock.count < self.num_tasks {
-            // We need a while loop to guard against spurious wakeups.
-            // http://en.wikipedia.org/wiki/Spurious_wakeup
-            while local_gen == lock.generation_id &&
-                  lock.count < self.num_tasks {
-                lock.cond.wait();
-            }
-        } else {
-            lock.count = 0;
-            lock.generation_id += 1;
-            lock.cond.broadcast();
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use comm::Empty;
-    use task;
-    use task::try_future;
-    use sync::Arc;
-
-    use super::{Mutex, Barrier, RWLock};
-
-    #[test]
-    fn test_mutex_arc_condvar() {
-        let arc = Arc::new(Mutex::new(false));
-        let arc2 = arc.clone();
-        let (tx, rx) = channel();
-        task::spawn(proc() {
-            // wait until parent gets in
-            rx.recv();
-            let mut lock = arc2.lock();
-            *lock = true;
-            lock.cond.signal();
-        });
-
-        let lock = arc.lock();
-        tx.send(());
-        assert!(!*lock);
-        while !*lock {
-            lock.cond.wait();
-        }
-    }
-
-    #[test] #[should_fail]
-    fn test_arc_condvar_poison() {
-        let arc = Arc::new(Mutex::new(1i));
-        let arc2 = arc.clone();
-        let (tx, rx) = channel();
-
-        spawn(proc() {
-            rx.recv();
-            let lock = arc2.lock();
-            lock.cond.signal();
-            // Parent should fail when it wakes up.
-            panic!();
-        });
-
-        let lock = arc.lock();
-        tx.send(());
-        while *lock == 1 {
-            lock.cond.wait();
-        }
-    }
-
-    #[test] #[should_fail]
-    fn test_mutex_arc_poison() {
-        let arc = Arc::new(Mutex::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try(proc() {
-            let lock = arc2.lock();
-            assert_eq!(*lock, 2);
-        });
-        let lock = arc.lock();
-        assert_eq!(*lock, 1);
-    }
-
-    #[test]
-    fn test_mutex_arc_nested() {
-        // Tests nested mutexes and access
-        // to underlying data.
-        let arc = Arc::new(Mutex::new(1i));
-        let arc2 = Arc::new(Mutex::new(arc));
-        task::spawn(proc() {
-            let lock = arc2.lock();
-            let lock2 = lock.deref().lock();
-            assert_eq!(*lock2, 1);
-        });
-    }
-
-    #[test]
-    fn test_mutex_arc_access_in_unwind() {
-        let arc = Arc::new(Mutex::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try::<()>(proc() {
-            struct Unwinder {
-                i: Arc<Mutex<int>>,
-            }
-            impl Drop for Unwinder {
-                fn drop(&mut self) {
-                    let mut lock = self.i.lock();
-                    *lock += 1;
-                }
-            }
-            let _u = Unwinder { i: arc2 };
-            panic!();
-        });
-        let lock = arc.lock();
-        assert_eq!(*lock, 2);
-    }
-
-    #[test] #[should_fail]
-    fn test_rw_arc_poison_wr() {
-        let arc = Arc::new(RWLock::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try(proc() {
-            let lock = arc2.write();
-            assert_eq!(*lock, 2);
-        });
-        let lock = arc.read();
-        assert_eq!(*lock, 1);
-    }
-    #[test] #[should_fail]
-    fn test_rw_arc_poison_ww() {
-        let arc = Arc::new(RWLock::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try(proc() {
-            let lock = arc2.write();
-            assert_eq!(*lock, 2);
-        });
-        let lock = arc.write();
-        assert_eq!(*lock, 1);
-    }
-    #[test]
-    fn test_rw_arc_no_poison_rr() {
-        let arc = Arc::new(RWLock::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try(proc() {
-            let lock = arc2.read();
-            assert_eq!(*lock, 2);
-        });
-        let lock = arc.read();
-        assert_eq!(*lock, 1);
-    }
-    #[test]
-    fn test_rw_arc_no_poison_rw() {
-        let arc = Arc::new(RWLock::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try(proc() {
-            let lock = arc2.read();
-            assert_eq!(*lock, 2);
-        });
-        let lock = arc.write();
-        assert_eq!(*lock, 1);
-    }
-    #[test]
-    fn test_rw_arc_no_poison_dr() {
-        let arc = Arc::new(RWLock::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try(proc() {
-            let lock = arc2.write().downgrade();
-            assert_eq!(*lock, 2);
-        });
-        let lock = arc.write();
-        assert_eq!(*lock, 1);
-    }
-
-    #[test]
-    fn test_rw_arc() {
-        let arc = Arc::new(RWLock::new(0i));
-        let arc2 = arc.clone();
-        let (tx, rx) = channel();
-
-        task::spawn(proc() {
-            let mut lock = arc2.write();
-            for _ in range(0u, 10) {
-                let tmp = *lock;
-                *lock = -1;
-                task::deschedule();
-                *lock = tmp + 1;
-            }
-            tx.send(());
-        });
-
-        // Readers try to catch the writer in the act
-        let mut children = Vec::new();
-        for _ in range(0u, 5) {
-            let arc3 = arc.clone();
-            children.push(try_future(proc() {
-                let lock = arc3.read();
-                assert!(*lock >= 0);
-            }));
-        }
-
-        // Wait for children to pass their asserts
-        for r in children.iter_mut() {
-            assert!(r.get_ref().is_ok());
-        }
-
-        // Wait for writer to finish
-        rx.recv();
-        let lock = arc.read();
-        assert_eq!(*lock, 10);
-    }
-
-    #[test]
-    fn test_rw_arc_access_in_unwind() {
-        let arc = Arc::new(RWLock::new(1i));
-        let arc2 = arc.clone();
-        let _ = task::try::<()>(proc() {
-            struct Unwinder {
-                i: Arc<RWLock<int>>,
-            }
-            impl Drop for Unwinder {
-                fn drop(&mut self) {
-                    let mut lock = self.i.write();
-                    *lock += 1;
-                }
-            }
-            let _u = Unwinder { i: arc2 };
-            panic!();
-        });
-        let lock = arc.read();
-        assert_eq!(*lock, 2);
-    }
-
-    #[test]
-    fn test_rw_downgrade() {
-        // (1) A downgrader gets in write mode and does cond.wait.
-        // (2) A writer gets in write mode, sets state to 42, and does signal.
-        // (3) Downgrader wakes, sets state to 31337.
-        // (4) tells writer and all other readers to contend as it downgrades.
-        // (5) Writer attempts to set state back to 42, while downgraded task
-        //     and all reader tasks assert that it's 31337.
-        let arc = Arc::new(RWLock::new(0i));
-
-        // Reader tasks
-        let mut reader_convos = Vec::new();
-        for _ in range(0u, 10) {
-            let ((tx1, rx1), (tx2, rx2)) = (channel(), channel());
-            reader_convos.push((tx1, rx2));
-            let arcn = arc.clone();
-            task::spawn(proc() {
-                rx1.recv(); // wait for downgrader to give go-ahead
-                let lock = arcn.read();
-                assert_eq!(*lock, 31337);
-                tx2.send(());
-            });
-        }
-
-        // Writer task
-        let arc2 = arc.clone();
-        let ((tx1, rx1), (tx2, rx2)) = (channel(), channel());
-        task::spawn(proc() {
-            rx1.recv();
-            {
-                let mut lock = arc2.write();
-                assert_eq!(*lock, 0);
-                *lock = 42;
-                lock.cond.signal();
-            }
-            rx1.recv();
-            {
-                let mut lock = arc2.write();
-                // This shouldn't happen until after the downgrade read
-                // section, and all other readers, finish.
-                assert_eq!(*lock, 31337);
-                *lock = 42;
-            }
-            tx2.send(());
-        });
-
-        // Downgrader (us)
-        let mut lock = arc.write();
-        tx1.send(()); // send to another writer who will wake us up
-        while *lock == 0 {
-            lock.cond.wait();
-        }
-        assert_eq!(*lock, 42);
-        *lock = 31337;
-        // send to other readers
-        for &(ref mut rc, _) in reader_convos.iter_mut() {
-            rc.send(())
-        }
-        let lock = lock.downgrade();
-        // complete handshake with other readers
-        for &(_, ref mut rp) in reader_convos.iter_mut() {
-            rp.recv()
-        }
-        tx1.send(()); // tell writer to try again
-        assert_eq!(*lock, 31337);
-        drop(lock);
-
-        rx2.recv(); // complete handshake with writer
-    }
-
-    #[cfg(test)]
-    fn test_rw_write_cond_downgrade_read_race_helper() {
-        // Tests that when a downgrader hands off the "reader cloud" lock
-        // because of a contending reader, a writer can't race to get it
-        // instead, which would result in readers_and_writers. This tests
-        // the raw module rather than this one, but it's here because an
-        // rwarc gives us extra shared state to help check for the race.
-        let x = Arc::new(RWLock::new(true));
-        let (tx, rx) = channel();
-
-        // writer task
-        let xw = x.clone();
-        task::spawn(proc() {
-            let mut lock = xw.write();
-            tx.send(()); // tell downgrader it's ok to go
-            lock.cond.wait();
-            // The core of the test is here: the condvar reacquire path
-            // must involve order_lock, so that it cannot race with a reader
-            // trying to receive the "reader cloud lock hand-off".
-            *lock = false;
-        });
-
-        rx.recv(); // wait for writer to get in
-
-        let lock = x.write();
-        assert!(*lock);
-        // make writer contend in the cond-reacquire path
-        lock.cond.signal();
-        // make a reader task to trigger the "reader cloud lock" handoff
-        let xr = x.clone();
-        let (tx, rx) = channel();
-        task::spawn(proc() {
-            tx.send(());
-            drop(xr.read());
-        });
-        rx.recv(); // wait for reader task to exist
-
-        let lock = lock.downgrade();
-        // if writer mistakenly got in, make sure it mutates state
-        // before we assert on it
-        for _ in range(0u, 5) { task::deschedule(); }
-        // make sure writer didn't get in.
-        assert!(*lock);
-    }
-    #[test]
-    fn test_rw_write_cond_downgrade_read_race() {
-        // Ideally the above test case would have deschedule statements in it
-        // that helped to expose the race nearly 100% of the time... but adding
-        // deschedules in the intuitively-right locations made it even less
-        // likely, and I wasn't sure why :( . This is a mediocre "next best"
-        // option.
-        for _ in range(0u, 8) {
-            test_rw_write_cond_downgrade_read_race_helper();
-        }
-    }
-
-    #[test]
-    fn test_barrier() {
-        let barrier = Arc::new(Barrier::new(10));
-        let (tx, rx) = channel();
-
-        for _ in range(0u, 9) {
-            let c = barrier.clone();
-            let tx = tx.clone();
-            spawn(proc() {
-                c.wait();
-                tx.send(true);
-            });
-        }
-
-        // At this point, all spawned tasks should be blocked,
-        // so we shouldn't get anything from the port
-        assert!(match rx.try_recv() {
-            Err(Empty) => true,
-            _ => false,
-        });
-
-        barrier.wait();
-        // Now, the barrier is cleared and we should get data.
-        for _ in range(0u, 9) {
-            rx.recv();
-        }
-    }
-}
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index 944b852db35..7605a6a96a0 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -17,41 +17,27 @@
 
 #![experimental]
 
-pub use self::one::{Once, ONCE_INIT};
-
 pub use alloc::arc::{Arc, Weak};
-pub use self::lock::{Mutex, MutexGuard, Condvar, Barrier,
-                     RWLock, RWLockReadGuard, RWLockWriteGuard};
 
-// The mutex/rwlock in this module are not meant for reexport
-pub use self::raw::{Semaphore, SemaphoreGuard};
+pub use self::mutex::{Mutex, MutexGuard, StaticMutex, StaticMutexGuard, MUTEX_INIT};
+pub use self::rwlock::{RWLock, StaticRWLock, RWLOCK_INIT};
+pub use self::rwlock::{RWLockReadGuard, RWLockWriteGuard};
+pub use self::rwlock::{StaticRWLockReadGuard, StaticRWLockWriteGuard};
+pub use self::condvar::{Condvar, StaticCondvar, CONDVAR_INIT, AsMutexGuard};
+pub use self::once::{Once, ONCE_INIT};
+pub use self::semaphore::{Semaphore, SemaphoreGuard};
+pub use self::barrier::Barrier;
 
 pub use self::future::Future;
 pub use self::task_pool::TaskPool;
 
-// Core building blocks for all primitives in this crate
-
-#[stable]
 pub mod atomic;
-
-// Concurrent data structures
-
-pub mod spsc_queue;
-pub mod mpsc_queue;
-pub mod mpmc_bounded_queue;
-pub mod deque;
-
-// Low-level concurrency primitives
-
-mod raw;
-mod mutex;
-mod one;
-
-// Higher level primitives based on those above
-
-mod lock;
-
-// Task management
-
+mod barrier;
+mod condvar;
 mod future;
+mod mutex;
+mod once;
+mod poison;
+mod rwlock;
+mod semaphore;
 mod task_pool;
diff --git a/src/libstd/sync/mpmc_bounded_queue.rs b/src/libstd/sync/mpmc_bounded_queue.rs
deleted file mode 100644
index dca2d4098c6..00000000000
--- a/src/libstd/sync/mpmc_bounded_queue.rs
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
-
-#![experimental]
-#![allow(missing_docs, dead_code)]
-
-// http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue
-
-use core::prelude::*;
-
-use alloc::arc::Arc;
-use vec::Vec;
-use core::num::UnsignedInt;
-use core::cell::UnsafeCell;
-
-use sync::atomic::{AtomicUint,Relaxed,Release,Acquire};
-
-struct Node<T> {
-    sequence: AtomicUint,
-    value: Option<T>,
-}
-
-struct State<T> {
-    pad0: [u8, ..64],
-    buffer: Vec<UnsafeCell<Node<T>>>,
-    mask: uint,
-    pad1: [u8, ..64],
-    enqueue_pos: AtomicUint,
-    pad2: [u8, ..64],
-    dequeue_pos: AtomicUint,
-    pad3: [u8, ..64],
-}
-
-pub struct Queue<T> {
-    state: Arc<State<T>>,
-}
-
-impl<T: Send> State<T> {
-    fn with_capacity(capacity: uint) -> State<T> {
-        let capacity = if capacity < 2 || (capacity & (capacity - 1)) != 0 {
-            if capacity < 2 {
-                2u
-            } else {
-                // use next power of 2 as capacity
-                capacity.next_power_of_two()
-            }
-        } else {
-            capacity
-        };
-        let buffer = Vec::from_fn(capacity, |i| {
-            UnsafeCell::new(Node { sequence:AtomicUint::new(i), value: None })
-        });
-        State{
-            pad0: [0, ..64],
-            buffer: buffer,
-            mask: capacity-1,
-            pad1: [0, ..64],
-            enqueue_pos: AtomicUint::new(0),
-            pad2: [0, ..64],
-            dequeue_pos: AtomicUint::new(0),
-            pad3: [0, ..64],
-        }
-    }
-
-    fn push(&self, value: T) -> bool {
-        let mask = self.mask;
-        let mut pos = self.enqueue_pos.load(Relaxed);
-        loop {
-            let node = &self.buffer[pos & mask];
-            let seq = unsafe { (*node.get()).sequence.load(Acquire) };
-            let diff: int = seq as int - pos as int;
-
-            if diff == 0 {
-                let enqueue_pos = self.enqueue_pos.compare_and_swap(pos, pos+1, Relaxed);
-                if enqueue_pos == pos {
-                    unsafe {
-                        (*node.get()).value = Some(value);
-                        (*node.get()).sequence.store(pos+1, Release);
-                    }
-                    break
-                } else {
-                    pos = enqueue_pos;
-                }
-            } else if diff < 0 {
-                return false
-            } else {
-                pos = self.enqueue_pos.load(Relaxed);
-            }
-        }
-        true
-    }
-
-    fn pop(&self) -> Option<T> {
-        let mask = self.mask;
-        let mut pos = self.dequeue_pos.load(Relaxed);
-        loop {
-            let node = &self.buffer[pos & mask];
-            let seq = unsafe { (*node.get()).sequence.load(Acquire) };
-            let diff: int = seq as int - (pos + 1) as int;
-            if diff == 0 {
-                let dequeue_pos = self.dequeue_pos.compare_and_swap(pos, pos+1, Relaxed);
-                if dequeue_pos == pos {
-                    unsafe {
-                        let value = (*node.get()).value.take();
-                        (*node.get()).sequence.store(pos + mask + 1, Release);
-                        return value
-                    }
-                } else {
-                    pos = dequeue_pos;
-                }
-            } else if diff < 0 {
-                return None
-            } else {
-                pos = self.dequeue_pos.load(Relaxed);
-            }
-        }
-    }
-}
-
-impl<T: Send> Queue<T> {
-    pub fn with_capacity(capacity: uint) -> Queue<T> {
-        Queue{
-            state: Arc::new(State::with_capacity(capacity))
-        }
-    }
-
-    pub fn push(&self, value: T) -> bool {
-        self.state.push(value)
-    }
-
-    pub fn pop(&self) -> Option<T> {
-        self.state.pop()
-    }
-}
-
-impl<T: Send> Clone for Queue<T> {
-    fn clone(&self) -> Queue<T> {
-        Queue { state: self.state.clone() }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use super::Queue;
-
-    #[test]
-    fn test() {
-        let nthreads = 8u;
-        let nmsgs = 1000u;
-        let q = Queue::with_capacity(nthreads*nmsgs);
-        assert_eq!(None, q.pop());
-        let (tx, rx) = channel();
-
-        for _ in range(0, nthreads) {
-            let q = q.clone();
-            let tx = tx.clone();
-            spawn(proc() {
-                let q = q;
-                for i in range(0, nmsgs) {
-                    assert!(q.push(i));
-                }
-                tx.send(());
-            });
-        }
-
-        let mut completion_rxs = vec![];
-        for _ in range(0, nthreads) {
-            let (tx, rx) = channel();
-            completion_rxs.push(rx);
-            let q = q.clone();
-            spawn(proc() {
-                let q = q;
-                let mut i = 0u;
-                loop {
-                    match q.pop() {
-                        None => {},
-                        Some(_) => {
-                            i += 1;
-                            if i == nmsgs { break }
-                        }
-                    }
-                }
-                tx.send(i);
-            });
-        }
-
-        for rx in completion_rxs.iter_mut() {
-            assert_eq!(nmsgs, rx.recv());
-        }
-        for _ in range(0, nthreads) {
-            rx.recv();
-        }
-    }
-}
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index c9e90210c30..4e07d54c57e 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -8,43 +8,68 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! A simple native mutex implementation. Warning: this API is likely
-//! to change soon.
+use prelude::*;
 
-#![allow(dead_code)]
-
-use core::prelude::*;
-use alloc::boxed::Box;
-use rustrt::mutex;
-
-pub const LOCKED: uint = 1 << 0;
-pub const BLOCKED: uint = 1 << 1;
+use cell::UnsafeCell;
+use kinds::marker;
+use sync::{poison, AsMutexGuard};
+use sys_common::mutex as sys;
 
 /// A mutual exclusion primitive useful for protecting shared data
 ///
-/// This mutex will properly block tasks waiting for the lock to become
-/// available. The mutex can also be statically initialized or created via a
-/// `new` constructor.
+/// This mutex will block threads waiting for the lock to become available. The
+/// mutex can also be statically initialized or created via a `new`
+/// constructor. Each mutex has a type parameter which represents the data that
+/// it is protecting. The data can only be accessed through the RAII guards
+/// returned from `lock` and `try_lock`, which guarantees that the data is only
+/// ever accessed when the mutex is locked.
+///
+/// # Poisoning
+///
+/// In order to prevent access to otherwise invalid data, each mutex will
+/// propagate any panics which occur while the lock is held. Once a thread has
+/// panicked while holding the lock, then all other threads will immediately
+/// panic as well once they hold the lock.
 ///
 /// # Example
 ///
-/// ```rust,ignore
-/// use std::sync::mutex::Mutex;
+/// ```rust
+/// use std::sync::{Arc, Mutex};
+/// const N: uint = 10;
 ///
-/// let m = Mutex::new();
-/// let guard = m.lock();
-/// // do some work
-/// drop(guard); // unlock the lock
+/// // Spawn a few threads to increment a shared variable (non-atomically), and
+/// // let the main thread know once all increments are done.
+/// //
+/// // Here we're using an Arc to share memory among tasks, and the data inside
+/// // the Arc is protected with a mutex.
+/// let data = Arc::new(Mutex::new(0));
+///
+/// let (tx, rx) = channel();
+/// for _ in range(0u, 10) {
+///     let (data, tx) = (data.clone(), tx.clone());
+///     spawn(proc() {
+///         // The shared static can only be accessed once the lock is held.
+///         // Our non-atomic increment is safe because we're the only thread
+///         // which can access the shared state when the lock is held.
+///         let mut data = data.lock();
+///         *data += 1;
+///         if *data == N {
+///             tx.send(());
+///         }
+///         // the lock is unlocked here when `data` goes out of scope.
+///     });
+/// }
+///
+/// rx.recv();
 /// ```
-pub struct Mutex {
+pub struct Mutex<T> {
     // Note that this static mutex is in a *box*, not inlined into the struct
-    // itself. This is done for memory safety reasons with the usage of a
-    // StaticNativeMutex inside the static mutex above. Once a native mutex has
-    // been used once, its address can never change (it can't be moved). This
-    // mutex type can be safely moved at any time, so to ensure that the native
-    // mutex is used correctly we box the inner lock to give it a constant
-    // address.
-    lock: Box<StaticMutex>,
+    // itself. Once a native mutex has been used once, its address can never
+    // change (it can't be moved). This mutex type can be safely moved at any
+    // time, so to ensure that the native mutex is used correctly we box the
+    // inner lock to give it a constant address.
+    inner: Box<StaticMutex>,
+    data: UnsafeCell<T>,
 }
 
 /// The static mutex type is provided to allow for static allocation of mutexes.
@@ -57,8 +82,8 @@ pub struct Mutex {
 ///
 /// # Example
 ///
-/// ```rust,ignore
-/// use std::sync::mutex::{StaticMutex, MUTEX_INIT};
+/// ```rust
+/// use std::sync::{StaticMutex, MUTEX_INIT};
 ///
 /// static LOCK: StaticMutex = MUTEX_INIT;
 ///
@@ -69,35 +94,113 @@ pub struct Mutex {
 /// // lock is unlocked here.
 /// ```
 pub struct StaticMutex {
-    lock: mutex::StaticNativeMutex,
+    lock: sys::Mutex,
+    poison: UnsafeCell<poison::Flag>,
 }
 
 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
 /// dropped (falls out of scope), the lock will be unlocked.
+///
+/// The data protected by the mutex can be access through this guard via its
+/// Deref and DerefMut implementations
 #[must_use]
-pub struct Guard<'a> {
-    guard: mutex::LockGuard<'a>,
+pub struct MutexGuard<'a, T: 'a> {
+    // funny underscores due to how Deref/DerefMut currently work (they
+    // disregard field privacy).
+    __lock: &'a Mutex<T>,
+    __guard: StaticMutexGuard,
 }
 
-fn lift_guard(guard: mutex::LockGuard) -> Guard {
-    Guard { guard: guard }
+/// An RAII implementation of a "scoped lock" of a static mutex. When this
+/// structure is dropped (falls out of scope), the lock will be unlocked.
+#[must_use]
+pub struct StaticMutexGuard {
+    lock: &'static sys::Mutex,
+    marker: marker::NoSend,
+    poison: poison::Guard<'static>,
 }
 
 /// Static initialization of a mutex. This constant can be used to initialize
 /// other mutex constants.
 pub const MUTEX_INIT: StaticMutex = StaticMutex {
-    lock: mutex::NATIVE_MUTEX_INIT
+    lock: sys::MUTEX_INIT,
+    poison: UnsafeCell { value: poison::Flag { failed: false } },
 };
 
-impl StaticMutex {
-    /// Attempts to grab this lock, see `Mutex::try_lock`
-    pub fn try_lock<'a>(&'a self) -> Option<Guard<'a>> {
-        unsafe { self.lock.trylock().map(lift_guard) }
+impl<T: Send> Mutex<T> {
+    /// Creates a new mutex in an unlocked state ready for use.
+    pub fn new(t: T) -> Mutex<T> {
+        Mutex {
+            inner: box MUTEX_INIT,
+            data: UnsafeCell::new(t),
+        }
+    }
+
+    /// Acquires a mutex, blocking the current task until it is able to do so.
+    ///
+    /// This function will block the local task until it is available to acquire
+    /// the mutex. Upon returning, the task is the only task with the mutex
+    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
+    /// the guard goes out of scope, the mutex will be unlocked.
+    ///
+    /// # Panics
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will immediately panic once the mutex is acquired.
+    pub fn lock(&self) -> MutexGuard<T> {
+        unsafe {
+            let lock: &'static StaticMutex = &*(&*self.inner as *const _);
+            MutexGuard::new(self, lock.lock())
+        }
+    }
+
+    /// Attempts to acquire this lock.
+    ///
+    /// If the lock could not be acquired at this time, then `None` is returned.
+    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
+    /// guard is dropped.
+    ///
+    /// This function does not block.
+    ///
+    /// # Panics
+    ///
+    /// If another user of this mutex panicked while holding the mutex, then
+    /// this call will immediately panic if the mutex would otherwise be
+    /// acquired.
+    pub fn try_lock(&self) -> Option<MutexGuard<T>> {
+        unsafe {
+            let lock: &'static StaticMutex = &*(&*self.inner as *const _);
+            lock.try_lock().map(|guard| {
+                MutexGuard::new(self, guard)
+            })
+        }
     }
+}
 
+#[unsafe_destructor]
+impl<T: Send> Drop for Mutex<T> {
+    fn drop(&mut self) {
+        // This is actually safe b/c we know that there is no further usage of
+        // this mutex (it's up to the user to arrange for a mutex to get
+        // dropped, that's not our job)
+        unsafe { self.inner.lock.destroy() }
+    }
+}
+
+impl StaticMutex {
     /// Acquires this lock, see `Mutex::lock`
-    pub fn lock<'a>(&'a self) -> Guard<'a> {
-        lift_guard(unsafe { self.lock.lock() })
+    pub fn lock(&'static self) -> StaticMutexGuard {
+        unsafe { self.lock.lock() }
+        StaticMutexGuard::new(self)
+    }
+
+    /// Attempts to grab this lock, see `Mutex::try_lock`
+    pub fn try_lock(&'static self) -> Option<StaticMutexGuard> {
+        if unsafe { self.lock.try_lock() } {
+            Some(StaticMutexGuard::new(self))
+        } else {
+            None
+        }
     }
 
     /// Deallocates resources associated with this static mutex.
@@ -110,58 +213,73 @@ impl StaticMutex {
     /// *all* platforms. It may be the case that some platforms do not leak
     /// memory if this method is not called, but this is not guaranteed to be
     /// true on all platforms.
-    pub unsafe fn destroy(&self) {
+    pub unsafe fn destroy(&'static self) {
         self.lock.destroy()
     }
 }
 
-impl Mutex {
-    /// Creates a new mutex in an unlocked state ready for use.
-    pub fn new() -> Mutex {
-        Mutex {
-            lock: box StaticMutex {
-                lock: unsafe { mutex::StaticNativeMutex::new() },
-            }
-        }
+impl<'mutex, T> MutexGuard<'mutex, T> {
+    fn new(lock: &Mutex<T>, guard: StaticMutexGuard) -> MutexGuard<T> {
+        MutexGuard { __lock: lock, __guard: guard }
     }
+}
 
-    /// Attempts to acquire this lock.
-    ///
-    /// If the lock could not be acquired at this time, then `None` is returned.
-    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
-    /// guard is dropped.
-    ///
-    /// This function does not block.
-    pub fn try_lock<'a>(&'a self) -> Option<Guard<'a>> {
-        self.lock.try_lock()
+impl<'mutex, T> AsMutexGuard for MutexGuard<'mutex, T> {
+    unsafe fn as_mutex_guard(&self) -> &StaticMutexGuard { &self.__guard }
+}
+
+impl<'mutex, T> Deref<T> for MutexGuard<'mutex, T> {
+    fn deref<'a>(&'a self) -> &'a T { unsafe { &*self.__lock.data.get() } }
+}
+impl<'mutex, T> DerefMut<T> for MutexGuard<'mutex, T> {
+    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
+        unsafe { &mut *self.__lock.data.get() }
     }
+}
 
-    /// Acquires a mutex, blocking the current task until it is able to do so.
-    ///
-    /// This function will block the local task until it is available to acquire
-    /// the mutex. Upon returning, the task is the only task with the mutex
-    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
-    /// the guard goes out of scope, the mutex will be unlocked.
-    pub fn lock<'a>(&'a self) -> Guard<'a> { self.lock.lock() }
+impl StaticMutexGuard {
+    fn new(lock: &'static StaticMutex) -> StaticMutexGuard {
+        unsafe {
+            let guard = StaticMutexGuard {
+                lock: &lock.lock,
+                marker: marker::NoSend,
+                poison: (*lock.poison.get()).borrow(),
+            };
+            guard.poison.check("mutex");
+            return guard;
+        }
+    }
+}
+
+pub fn guard_lock(guard: &StaticMutexGuard) -> &sys::Mutex { guard.lock }
+pub fn guard_poison(guard: &StaticMutexGuard) -> &poison::Guard {
+    &guard.poison
+}
+
+impl AsMutexGuard for StaticMutexGuard {
+    unsafe fn as_mutex_guard(&self) -> &StaticMutexGuard { self }
 }
 
-impl Drop for Mutex {
+#[unsafe_destructor]
+impl Drop for StaticMutexGuard {
     fn drop(&mut self) {
-        // This is actually safe b/c we know that there is no further usage of
-        // this mutex (it's up to the user to arrange for a mutex to get
-        // dropped, that's not our job)
-        unsafe { self.lock.destroy() }
+        unsafe {
+            self.poison.done();
+            self.lock.unlock();
+        }
     }
 }
 
 #[cfg(test)]
 mod test {
     use prelude::*;
-    use super::{Mutex, StaticMutex, MUTEX_INIT};
+
+    use task;
+    use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar};
 
     #[test]
     fn smoke() {
-        let m = Mutex::new();
+        let m = Mutex::new(());
         drop(m.lock());
         drop(m.lock());
     }
@@ -211,8 +329,104 @@ mod test {
     }
 
     #[test]
-    fn trylock() {
-        let m = Mutex::new();
+    fn try_lock() {
+        let m = Mutex::new(());
         assert!(m.try_lock().is_some());
     }
+
+    #[test]
+    fn test_mutex_arc_condvar() {
+        let arc = Arc::new((Mutex::new(false), Condvar::new()));
+        let arc2 = arc.clone();
+        let (tx, rx) = channel();
+        spawn(proc() {
+            // wait until parent gets in
+            rx.recv();
+            let &(ref lock, ref cvar) = &*arc2;
+            let mut lock = lock.lock();
+            *lock = true;
+            cvar.notify_one();
+        });
+
+        let &(ref lock, ref cvar) = &*arc;
+        let lock = lock.lock();
+        tx.send(());
+        assert!(!*lock);
+        while !*lock {
+            cvar.wait(&lock);
+        }
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_arc_condvar_poison() {
+        let arc = Arc::new((Mutex::new(1i), Condvar::new()));
+        let arc2 = arc.clone();
+        let (tx, rx) = channel();
+
+        spawn(proc() {
+            rx.recv();
+            let &(ref lock, ref cvar) = &*arc2;
+            let _g = lock.lock();
+            cvar.notify_one();
+            // Parent should fail when it wakes up.
+            panic!();
+        });
+
+        let &(ref lock, ref cvar) = &*arc;
+        let lock = lock.lock();
+        tx.send(());
+        while *lock == 1 {
+            cvar.wait(&lock);
+        }
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_mutex_arc_poison() {
+        let arc = Arc::new(Mutex::new(1i));
+        let arc2 = arc.clone();
+        let _ = task::try(proc() {
+            let lock = arc2.lock();
+            assert_eq!(*lock, 2);
+        });
+        let lock = arc.lock();
+        assert_eq!(*lock, 1);
+    }
+
+    #[test]
+    fn test_mutex_arc_nested() {
+        // Tests nested mutexes and access
+        // to underlying data.
+        let arc = Arc::new(Mutex::new(1i));
+        let arc2 = Arc::new(Mutex::new(arc));
+        let (tx, rx) = channel();
+        spawn(proc() {
+            let lock = arc2.lock();
+            let lock2 = lock.deref().lock();
+            assert_eq!(*lock2, 1);
+            tx.send(());
+        });
+        rx.recv();
+    }
+
+    #[test]
+    fn test_mutex_arc_access_in_unwind() {
+        let arc = Arc::new(Mutex::new(1i));
+        let arc2 = arc.clone();
+        let _ = task::try::<()>(proc() {
+            struct Unwinder {
+                i: Arc<Mutex<int>>,
+            }
+            impl Drop for Unwinder {
+                fn drop(&mut self) {
+                    *self.i.lock() += 1;
+                }
+            }
+            let _u = Unwinder { i: arc2 };
+            panic!();
+        });
+        let lock = arc.lock();
+        assert_eq!(*lock, 2);
+    }
 }
diff --git a/src/libstd/sync/one.rs b/src/libstd/sync/once.rs
index f710a6da59b..a75088120f8 100644
--- a/src/libstd/sync/one.rs
+++ b/src/libstd/sync/once.rs
@@ -13,12 +13,10 @@
 //! This primitive is meant to be used to run one-time initialization. An
 //! example use case would be for initializing an FFI library.
 
-use core::prelude::*;
-
-use core::int;
-use core::atomic;
-
-use super::mutex::{StaticMutex, MUTEX_INIT};
+use int;
+use mem::drop;
+use sync::atomic;
+use sync::{StaticMutex, MUTEX_INIT};
 
 /// A synchronization primitive which can be used to run a one-time global
 /// initialization. Useful for one-time initialization for FFI or related
@@ -27,8 +25,8 @@ use super::mutex::{StaticMutex, MUTEX_INIT};
 ///
 /// # Example
 ///
-/// ```rust,ignore
-/// use std::sync::one::{Once, ONCE_INIT};
+/// ```rust
+/// use std::sync::{Once, ONCE_INIT};
 ///
 /// static START: Once = ONCE_INIT;
 ///
@@ -59,7 +57,7 @@ impl Once {
     ///
     /// When this function returns, it is guaranteed that some initialization
     /// has run and completed (it may not be the closure specified).
-    pub fn doit(&self, f: ||) {
+    pub fn doit(&'static self, f: ||) {
         // Optimize common path: load is much cheaper than fetch_add.
         if self.cnt.load(atomic::SeqCst) < 0 {
             return
@@ -121,6 +119,7 @@ impl Once {
 #[cfg(test)]
 mod test {
     use prelude::*;
+
     use task;
     use super::{ONCE_INIT, Once};
 
diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs
new file mode 100644
index 00000000000..eb46fd77147
--- /dev/null
+++ b/src/libstd/sync/poison.rs
@@ -0,0 +1,48 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use option::None;
+use rustrt::task::Task;
+use rustrt::local::Local;
+
+pub struct Flag { pub failed: bool }
+
+impl Flag {
+    pub fn borrow(&mut self) -> Guard {
+        Guard { flag: &mut self.failed, failing: failing() }
+    }
+}
+
+pub struct Guard<'a> {
+    flag: &'a mut bool,
+    failing: bool,
+}
+
+impl<'a> Guard<'a> {
+    pub fn check(&self, name: &str) {
+        if *self.flag {
+            panic!("poisoned {} - another task failed inside", name);
+        }
+    }
+
+    pub fn done(&mut self) {
+        if !self.failing && failing() {
+            *self.flag = true;
+        }
+    }
+}
+
+fn failing() -> bool {
+    if Local::exists(None::<Task>) {
+        Local::borrow(None::<Task>).unwinder.unwinding()
+    } else {
+        false
+    }
+}
diff --git a/src/libstd/sync/raw.rs b/src/libstd/sync/raw.rs
deleted file mode 100644
index 47580a11513..00000000000
--- a/src/libstd/sync/raw.rs
+++ /dev/null
@@ -1,1132 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Raw concurrency primitives you know and love.
-//!
-//! These primitives are not recommended for general use, but are provided for
-//! flavorful use-cases. It is recommended to use the types at the top of the
-//! `sync` crate which wrap values directly and provide safer abstractions for
-//! containing data.
-
-// A side-effect of merging libsync into libstd; will go away once
-// libsync rewrite lands
-#![allow(dead_code)]
-
-use core::prelude::*;
-use self::ReacquireOrderLock::*;
-
-use core::atomic;
-use core::finally::Finally;
-use core::kinds::marker;
-use core::mem;
-use core::cell::UnsafeCell;
-use vec::Vec;
-
-use super::mutex;
-use comm::{Receiver, Sender, channel};
-
-// Each waiting task receives on one of these.
-type WaitEnd = Receiver<()>;
-type SignalEnd = Sender<()>;
-// A doubly-ended queue of waiting tasks.
-struct WaitQueue {
-    head: Receiver<SignalEnd>,
-    tail: Sender<SignalEnd>,
-}
-
-impl WaitQueue {
-    fn new() -> WaitQueue {
-        let (block_tail, block_head) = channel();
-        WaitQueue { head: block_head, tail: block_tail }
-    }
-
-    // Signals one live task from the queue.
-    fn signal(&self) -> bool {
-        match self.head.try_recv() {
-            Ok(ch) => {
-                // Send a wakeup signal. If the waiter was killed, its port will
-                // have closed. Keep trying until we get a live task.
-                if ch.send_opt(()).is_ok() {
-                    true
-                } else {
-                    self.signal()
-                }
-            }
-            _ => false
-        }
-    }
-
-    fn broadcast(&self) -> uint {
-        let mut count = 0;
-        loop {
-            match self.head.try_recv() {
-                Ok(ch) => {
-                    if ch.send_opt(()).is_ok() {
-                        count += 1;
-                    }
-                }
-                _ => break
-            }
-        }
-        count
-    }
-
-    fn wait_end(&self) -> WaitEnd {
-        let (signal_end, wait_end) = channel();
-        self.tail.send(signal_end);
-        wait_end
-    }
-}
-
-// The building-block used to make semaphores, mutexes, and rwlocks.
-struct Sem<Q> {
-    lock: mutex::Mutex,
-    // n.b, we need Sem to be `Sync`, but the WaitQueue type is not send/share
-    //      (for good reason). We have an internal invariant on this semaphore,
-    //      however, that the queue is never accessed outside of a locked
-    //      context.
-    inner: UnsafeCell<SemInner<Q>>
-}
-
-struct SemInner<Q> {
-    count: int,
-    waiters: WaitQueue,
-    // Can be either unit or another waitqueue. Some sems shouldn't come with
-    // a condition variable attached, others should.
-    blocked: Q,
-}
-
-#[must_use]
-struct SemGuard<'a, Q:'a> {
-    sem: &'a Sem<Q>,
-}
-
-impl<Q: Send> Sem<Q> {
-    fn new(count: int, q: Q) -> Sem<Q> {
-        assert!(count >= 0,
-                "semaphores cannot be initialized with negative values");
-        Sem {
-            lock: mutex::Mutex::new(),
-            inner: UnsafeCell::new(SemInner {
-                waiters: WaitQueue::new(),
-                count: count,
-                blocked: q,
-            })
-        }
-    }
-
-    unsafe fn with(&self, f: |&mut SemInner<Q>|) {
-        let _g = self.lock.lock();
-        // This &mut is safe because, due to the lock, we are the only one who can touch the data
-        f(&mut *self.inner.get())
-    }
-
-    pub fn acquire(&self) {
-        unsafe {
-            let mut waiter_nobe = None;
-            self.with(|state| {
-                state.count -= 1;
-                if state.count < 0 {
-                    // Create waiter nobe, enqueue ourself, and tell
-                    // outer scope we need to block.
-                    waiter_nobe = Some(state.waiters.wait_end());
-                }
-            });
-            // Uncomment if you wish to test for sem races. Not
-            // valgrind-friendly.
-            /* for _ in range(0u, 1000) { task::deschedule(); } */
-            // Need to wait outside the exclusive.
-            if waiter_nobe.is_some() {
-                let _ = waiter_nobe.unwrap().recv();
-            }
-        }
-    }
-
-    pub fn release(&self) {
-        unsafe {
-            self.with(|state| {
-                state.count += 1;
-                if state.count <= 0 {
-                    state.waiters.signal();
-                }
-            })
-        }
-    }
-
-    pub fn access<'a>(&'a self) -> SemGuard<'a, Q> {
-        self.acquire();
-        SemGuard { sem: self }
-    }
-}
-
-#[unsafe_destructor]
-impl<'a, Q: Send> Drop for SemGuard<'a, Q> {
-    fn drop(&mut self) {
-        self.sem.release();
-    }
-}
-
-impl Sem<Vec<WaitQueue>> {
-    fn new_and_signal(count: int, num_condvars: uint) -> Sem<Vec<WaitQueue>> {
-        let mut queues = Vec::new();
-        for _ in range(0, num_condvars) { queues.push(WaitQueue::new()); }
-        Sem::new(count, queues)
-    }
-
-    // The only other places that condvars get built are rwlock.write_cond()
-    // and rwlock_write_mode.
-    pub fn access_cond<'a>(&'a self) -> SemCondGuard<'a> {
-        SemCondGuard {
-            guard: self.access(),
-            cvar: Condvar { sem: self, order: Nothing, nocopy: marker::NoCopy },
-        }
-    }
-}
-
-// FIXME(#3598): Want to use an Option down below, but we need a custom enum
-// that's not polymorphic to get around the fact that lifetimes are invariant
-// inside of type parameters.
-enum ReacquireOrderLock<'a> {
-    Nothing, // c.c
-    Just(&'a Semaphore),
-}
-
-/// A mechanism for atomic-unlock-and-deschedule blocking and signalling.
-pub struct Condvar<'a> {
-    // The 'Sem' object associated with this condvar. This is the one that's
-    // atomically-unlocked-and-descheduled upon and reacquired during wakeup.
-    sem: &'a Sem<Vec<WaitQueue> >,
-    // This is (can be) an extra semaphore which is held around the reacquire
-    // operation on the first one. This is only used in cvars associated with
-    // rwlocks, and is needed to ensure that, when a downgrader is trying to
-    // hand off the access lock (which would be the first field, here), a 2nd
-    // writer waking up from a cvar wait can't race with a reader to steal it,
-    // See the comment in write_cond for more detail.
-    order: ReacquireOrderLock<'a>,
-    // Make sure condvars are non-copyable.
-    nocopy: marker::NoCopy,
-}
-
-impl<'a> Condvar<'a> {
-    /// Atomically drop the associated lock, and block until a signal is sent.
-    ///
-    /// # Panics
-    ///
-    /// A task which is killed while waiting on a condition variable will wake
-    /// up, panic, and unlock the associated lock as it unwinds.
-    pub fn wait(&self) { self.wait_on(0) }
-
-    /// As wait(), but can specify which of multiple condition variables to
-    /// wait on. Only a signal_on() or broadcast_on() with the same condvar_id
-    /// will wake this thread.
-    ///
-    /// The associated lock must have been initialised with an appropriate
-    /// number of condvars. The condvar_id must be between 0 and num_condvars-1
-    /// or else this call will panic.
-    ///
-    /// wait() is equivalent to wait_on(0).
-    pub fn wait_on(&self, condvar_id: uint) {
-        let mut wait_end = None;
-        let mut out_of_bounds = None;
-        // Release lock, 'atomically' enqueuing ourselves in so doing.
-        unsafe {
-            self.sem.with(|state| {
-                if condvar_id < state.blocked.len() {
-                    // Drop the lock.
-                    state.count += 1;
-                    if state.count <= 0 {
-                        state.waiters.signal();
-                    }
-                    // Create waiter nobe, and enqueue ourself to
-                    // be woken up by a signaller.
-                    wait_end = Some(state.blocked[condvar_id].wait_end());
-                } else {
-                    out_of_bounds = Some(state.blocked.len());
-                }
-            })
-        }
-
-        // If deschedule checks start getting inserted anywhere, we can be
-        // killed before or after enqueueing.
-        check_cvar_bounds(out_of_bounds, condvar_id, "cond.wait_on()", || {
-            // Unconditionally "block". (Might not actually block if a
-            // signaller already sent -- I mean 'unconditionally' in contrast
-            // with acquire().)
-            (|| {
-                let _ = wait_end.take().unwrap().recv();
-            }).finally(|| {
-                // Reacquire the condvar.
-                match self.order {
-                    Just(lock) => {
-                        let _g = lock.access();
-                        self.sem.acquire();
-                    }
-                    Nothing => self.sem.acquire(),
-                }
-            })
-        })
-    }
-
-    /// Wake up a blocked task. Returns false if there was no blocked task.
-    pub fn signal(&self) -> bool { self.signal_on(0) }
-
-    /// As signal, but with a specified condvar_id. See wait_on.
-    pub fn signal_on(&self, condvar_id: uint) -> bool {
-        unsafe {
-            let mut out_of_bounds = None;
-            let mut result = false;
-            self.sem.with(|state| {
-                if condvar_id < state.blocked.len() {
-                    result = state.blocked[condvar_id].signal();
-                } else {
-                    out_of_bounds = Some(state.blocked.len());
-                }
-            });
-            check_cvar_bounds(out_of_bounds,
-                              condvar_id,
-                              "cond.signal_on()",
-                              || result)
-        }
-    }
-
-    /// Wake up all blocked tasks. Returns the number of tasks woken.
-    pub fn broadcast(&self) -> uint { self.broadcast_on(0) }
-
-    /// As broadcast, but with a specified condvar_id. See wait_on.
-    pub fn broadcast_on(&self, condvar_id: uint) -> uint {
-        let mut out_of_bounds = None;
-        let mut queue = None;
-        unsafe {
-            self.sem.with(|state| {
-                if condvar_id < state.blocked.len() {
-                    // To avoid :broadcast_heavy, we make a new waitqueue,
-                    // swap it out with the old one, and broadcast on the
-                    // old one outside of the little-lock.
-                    queue = Some(mem::replace(&mut state.blocked[condvar_id],
-                                              WaitQueue::new()));
-                } else {
-                    out_of_bounds = Some(state.blocked.len());
-                }
-            });
-            check_cvar_bounds(out_of_bounds,
-                              condvar_id,
-                              "cond.signal_on()",
-                              || {
-                queue.take().unwrap().broadcast()
-            })
-        }
-    }
-}
-
-// Checks whether a condvar ID was out of bounds, and panics if so, or does
-// something else next on success.
-#[inline]
-fn check_cvar_bounds<U>(
-                     out_of_bounds: Option<uint>,
-                     id: uint,
-                     act: &str,
-                     blk: || -> U)
-                     -> U {
-    match out_of_bounds {
-        Some(0) =>
-            panic!("{} with illegal ID {} - this lock has no condvars!", act, id),
-        Some(length) =>
-            panic!("{} with illegal ID {} - ID must be less than {}", act, id, length),
-        None => blk()
-    }
-}
-
-#[must_use]
-struct SemCondGuard<'a> {
-    guard: SemGuard<'a, Vec<WaitQueue>>,
-    cvar: Condvar<'a>,
-}
-
-/// A counting, blocking, bounded-waiting semaphore.
-pub struct Semaphore {
-    sem: Sem<()>,
-}
-
-/// An RAII guard used to represent an acquired resource to a semaphore. When
-/// dropped, this value will release the resource back to the semaphore.
-#[must_use]
-pub struct SemaphoreGuard<'a> {
-    _guard: SemGuard<'a, ()>,
-}
-
-impl Semaphore {
-    /// Create a new semaphore with the specified count.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if `count` is negative.
-    pub fn new(count: int) -> Semaphore {
-        Semaphore { sem: Sem::new(count, ()) }
-    }
-
-    /// Acquire a resource represented by the semaphore. Blocks if necessary
-    /// until resource(s) become available.
-    pub fn acquire(&self) { self.sem.acquire() }
-
-    /// Release a held resource represented by the semaphore. Wakes a blocked
-    /// contending task, if any exist. Won't block the caller.
-    pub fn release(&self) { self.sem.release() }
-
-    /// Acquire a resource of this semaphore, returning an RAII guard which will
-    /// release the resource when dropped.
-    pub fn access<'a>(&'a self) -> SemaphoreGuard<'a> {
-        SemaphoreGuard { _guard: self.sem.access() }
-    }
-}
-
-/// A blocking, bounded-waiting, mutual exclusion lock with an associated
-/// FIFO condition variable.
-///
-/// # Panics
-///
-/// A task which panicks while holding a mutex will unlock the mutex as it
-/// unwinds.
-pub struct Mutex {
-    sem: Sem<Vec<WaitQueue>>,
-}
-
-/// An RAII structure which is used to gain access to a mutex's condition
-/// variable. Additionally, when a value of this type is dropped, the
-/// corresponding mutex is also unlocked.
-#[must_use]
-pub struct MutexGuard<'a> {
-    _guard: SemGuard<'a, Vec<WaitQueue>>,
-    /// Inner condition variable which is connected to the outer mutex, and can
-    /// be used for atomic-unlock-and-deschedule.
-    pub cond: Condvar<'a>,
-}
-
-impl Mutex {
-    /// Create a new mutex, with one associated condvar.
-    pub fn new() -> Mutex { Mutex::new_with_condvars(1) }
-
-    /// Create a new mutex, with a specified number of associated condvars. This
-    /// will allow calling wait_on/signal_on/broadcast_on with condvar IDs
-    /// between 0 and num_condvars-1. (If num_condvars is 0, lock_cond will be
-    /// allowed but any operations on the condvar will panic.)
-    pub fn new_with_condvars(num_condvars: uint) -> Mutex {
-        Mutex { sem: Sem::new_and_signal(1, num_condvars) }
-    }
-
-    /// Acquires ownership of this mutex, returning an RAII guard which will
-    /// unlock the mutex when dropped. The associated condition variable can
-    /// also be accessed through the returned guard.
-    pub fn lock<'a>(&'a self) -> MutexGuard<'a> {
-        let SemCondGuard { guard, cvar } = self.sem.access_cond();
-        MutexGuard { _guard: guard, cond: cvar }
-    }
-}
-
-// NB: Wikipedia - Readers-writers_problem#The_third_readers-writers_problem
-
-/// A blocking, no-starvation, reader-writer lock with an associated condvar.
-///
-/// # Panics
-///
-/// A task which panics while holding an rwlock will unlock the rwlock as it
-/// unwinds.
-pub struct RWLock {
-    order_lock:  Semaphore,
-    access_lock: Sem<Vec<WaitQueue>>,
-
-    // The only way the count flag is ever accessed is with xadd. Since it is
-    // a read-modify-write operation, multiple xadds on different cores will
-    // always be consistent with respect to each other, so a monotonic/relaxed
-    // consistency ordering suffices (i.e., no extra barriers are needed).
-    //
-    // FIXME(#6598): The atomics module has no relaxed ordering flag, so I use
-    // acquire/release orderings superfluously. Change these someday.
-    read_count: atomic::AtomicUint,
-}
-
-/// An RAII helper which is created by acquiring a read lock on an RWLock. When
-/// dropped, this will unlock the RWLock.
-#[must_use]
-pub struct RWLockReadGuard<'a> {
-    lock: &'a RWLock,
-}
-
-/// An RAII helper which is created by acquiring a write lock on an RWLock. When
-/// dropped, this will unlock the RWLock.
-///
-/// A value of this type can also be consumed to downgrade to a read-only lock.
-#[must_use]
-pub struct RWLockWriteGuard<'a> {
-    lock: &'a RWLock,
-    /// Inner condition variable that is connected to the write-mode of the
-    /// outer rwlock.
-    pub cond: Condvar<'a>,
-}
-
-impl RWLock {
-    /// Create a new rwlock, with one associated condvar.
-    pub fn new() -> RWLock { RWLock::new_with_condvars(1) }
-
-    /// Create a new rwlock, with a specified number of associated condvars.
-    /// Similar to mutex_with_condvars.
-    pub fn new_with_condvars(num_condvars: uint) -> RWLock {
-        RWLock {
-            order_lock: Semaphore::new(1),
-            access_lock: Sem::new_and_signal(1, num_condvars),
-            read_count: atomic::AtomicUint::new(0),
-        }
-    }
-
-    /// Acquires a read-lock, returning an RAII guard that will unlock the lock
-    /// when dropped. Calls to 'read' from other tasks may run concurrently with
-    /// this one.
-    pub fn read<'a>(&'a self) -> RWLockReadGuard<'a> {
-        let _guard = self.order_lock.access();
-        let old_count = self.read_count.fetch_add(1, atomic::Acquire);
-        if old_count == 0 {
-            self.access_lock.acquire();
-        }
-        RWLockReadGuard { lock: self }
-    }
-
-    /// Acquire a write-lock, returning an RAII guard that will unlock the lock
-    /// when dropped. No calls to 'read' or 'write' from other tasks will run
-    /// concurrently with this one.
-    ///
-    /// You can also downgrade a write to a read by calling the `downgrade`
-    /// method on the returned guard. Additionally, the guard will contain a
-    /// `Condvar` attached to this lock.
-    ///
-    /// # Example
-    ///
-    /// ```{rust,ignore}
-    /// use std::sync::raw::RWLock;
-    ///
-    /// let lock = RWLock::new();
-    /// let write = lock.write();
-    /// // ... exclusive access ...
-    /// let read = write.downgrade();
-    /// // ... shared access ...
-    /// drop(read);
-    /// ```
-    pub fn write<'a>(&'a self) -> RWLockWriteGuard<'a> {
-        let _g = self.order_lock.access();
-        self.access_lock.acquire();
-
-        // It's important to thread our order lock into the condvar, so that
-        // when a cond.wait() wakes up, it uses it while reacquiring the
-        // access lock. If we permitted a waking-up writer to "cut in line",
-        // there could arise a subtle race when a downgrader attempts to hand
-        // off the reader cloud lock to a waiting reader. This race is tested
-        // in arc.rs (test_rw_write_cond_downgrade_read_race) and looks like:
-        // T1 (writer)              T2 (downgrader)             T3 (reader)
-        // [in cond.wait()]
-        //                          [locks for writing]
-        //                          [holds access_lock]
-        // [is signalled, perhaps by
-        //  downgrader or a 4th thread]
-        // tries to lock access(!)
-        //                                                      lock order_lock
-        //                                                      xadd read_count[0->1]
-        //                                                      tries to lock access
-        //                          [downgrade]
-        //                          xadd read_count[1->2]
-        //                          unlock access
-        // Since T1 contended on the access lock before T3 did, it will steal
-        // the lock handoff. Adding order_lock in the condvar reacquire path
-        // solves this because T1 will hold order_lock while waiting on access,
-        // which will cause T3 to have to wait until T1 finishes its write,
-        // which can't happen until T2 finishes the downgrade-read entirely.
-        // The astute reader will also note that making waking writers use the
-        // order_lock is better for not starving readers.
-        RWLockWriteGuard {
-            lock: self,
-            cond: Condvar {
-                sem: &self.access_lock,
-                order: Just(&self.order_lock),
-                nocopy: marker::NoCopy,
-            }
-        }
-    }
-}
-
-impl<'a> RWLockWriteGuard<'a> {
-    /// Consumes this write lock and converts it into a read lock.
-    pub fn downgrade(self) -> RWLockReadGuard<'a> {
-        let lock = self.lock;
-        // Don't run the destructor of the write guard, we're in charge of
-        // things from now on
-        unsafe { mem::forget(self) }
-
-        let old_count = lock.read_count.fetch_add(1, atomic::Release);
-        // If another reader was already blocking, we need to hand-off
-        // the "reader cloud" access lock to them.
-        if old_count != 0 {
-            // Guaranteed not to let another writer in, because
-            // another reader was holding the order_lock. Hence they
-            // must be the one to get the access_lock (because all
-            // access_locks are acquired with order_lock held). See
-            // the comment in write_cond for more justification.
-            lock.access_lock.release();
-        }
-        RWLockReadGuard { lock: lock }
-    }
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for RWLockWriteGuard<'a> {
-    fn drop(&mut self) {
-        self.lock.access_lock.release();
-    }
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for RWLockReadGuard<'a> {
-    fn drop(&mut self) {
-        let old_count = self.lock.read_count.fetch_sub(1, atomic::Release);
-        assert!(old_count > 0);
-        if old_count == 1 {
-            // Note: this release used to be outside of a locked access
-            // to exclusive-protected state. If this code is ever
-            // converted back to such (instead of using atomic ops),
-            // this access MUST NOT go inside the exclusive access.
-            self.lock.access_lock.release();
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    pub use self::RWLockMode::*;
-
-    use sync::Arc;
-    use prelude::*;
-    use super::{Semaphore, Mutex, RWLock, Condvar};
-
-    use mem;
-    use result;
-    use task;
-
-    #[test]
-    fn test_sem_acquire_release() {
-        let s = Semaphore::new(1);
-        s.acquire();
-        s.release();
-        s.acquire();
-    }
-
-    #[test]
-    fn test_sem_basic() {
-        let s = Semaphore::new(1);
-        let _g = s.access();
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_sem_basic2() {
-        Semaphore::new(-1);
-    }
-
-    #[test]
-    fn test_sem_as_mutex() {
-        let s = Arc::new(Semaphore::new(1));
-        let s2 = s.clone();
-        task::spawn(proc() {
-            let _g = s2.access();
-            for _ in range(0u, 5) { task::deschedule(); }
-        });
-        let _g = s.access();
-        for _ in range(0u, 5) { task::deschedule(); }
-    }
-
-    #[test]
-    fn test_sem_as_cvar() {
-        /* Child waits and parent signals */
-        let (tx, rx) = channel();
-        let s = Arc::new(Semaphore::new(0));
-        let s2 = s.clone();
-        task::spawn(proc() {
-            s2.acquire();
-            tx.send(());
-        });
-        for _ in range(0u, 5) { task::deschedule(); }
-        s.release();
-        let _ = rx.recv();
-
-        /* Parent waits and child signals */
-        let (tx, rx) = channel();
-        let s = Arc::new(Semaphore::new(0));
-        let s2 = s.clone();
-        task::spawn(proc() {
-            for _ in range(0u, 5) { task::deschedule(); }
-            s2.release();
-            let _ = rx.recv();
-        });
-        s.acquire();
-        tx.send(());
-    }
-
-    #[test]
-    fn test_sem_multi_resource() {
-        // Parent and child both get in the critical section at the same
-        // time, and shake hands.
-        let s = Arc::new(Semaphore::new(2));
-        let s2 = s.clone();
-        let (tx1, rx1) = channel();
-        let (tx2, rx2) = channel();
-        task::spawn(proc() {
-            let _g = s2.access();
-            let _ = rx2.recv();
-            tx1.send(());
-        });
-        let _g = s.access();
-        tx2.send(());
-        let _ = rx1.recv();
-    }
-
-    #[test]
-    fn test_sem_runtime_friendly_blocking() {
-        // Force the runtime to schedule two threads on the same sched_loop.
-        // When one blocks, it should schedule the other one.
-        let s = Arc::new(Semaphore::new(1));
-        let s2 = s.clone();
-        let (tx, rx) = channel();
-        {
-            let _g = s.access();
-            task::spawn(proc() {
-                tx.send(());
-                drop(s2.access());
-                tx.send(());
-            });
-            rx.recv(); // wait for child to come alive
-            for _ in range(0u, 5) { task::deschedule(); } // let the child contend
-        }
-        rx.recv(); // wait for child to be done
-    }
-
-    #[test]
-    fn test_mutex_lock() {
-        // Unsafely achieve shared state, and do the textbook
-        // "load tmp = move ptr; inc tmp; store ptr <- tmp" dance.
-        let (tx, rx) = channel();
-        let m = Arc::new(Mutex::new());
-        let m2 = m.clone();
-        let mut sharedstate = box 0;
-        {
-            let ptr: *mut int = &mut *sharedstate;
-            task::spawn(proc() {
-                access_shared(ptr, &m2, 10);
-                tx.send(());
-            });
-        }
-        {
-            access_shared(&mut *sharedstate, &m, 10);
-            let _ = rx.recv();
-
-            assert_eq!(*sharedstate, 20);
-        }
-
-        fn access_shared(sharedstate: *mut int, m: &Arc<Mutex>, n: uint) {
-            for _ in range(0u, n) {
-                let _g = m.lock();
-                let oldval = unsafe { *sharedstate };
-                task::deschedule();
-                unsafe { *sharedstate = oldval + 1; }
-            }
-        }
-    }
-
-    #[test]
-    fn test_mutex_cond_wait() {
-        let m = Arc::new(Mutex::new());
-
-        // Child wakes up parent
-        {
-            let lock = m.lock();
-            let m2 = m.clone();
-            task::spawn(proc() {
-                let lock = m2.lock();
-                let woken = lock.cond.signal();
-                assert!(woken);
-            });
-            lock.cond.wait();
-        }
-        // Parent wakes up child
-        let (tx, rx) = channel();
-        let m3 = m.clone();
-        task::spawn(proc() {
-            let lock = m3.lock();
-            tx.send(());
-            lock.cond.wait();
-            tx.send(());
-        });
-        rx.recv(); // Wait until child gets in the mutex
-        {
-            let lock = m.lock();
-            let woken = lock.cond.signal();
-            assert!(woken);
-        }
-        rx.recv(); // Wait until child wakes up
-    }
-
-    fn test_mutex_cond_broadcast_helper(num_waiters: uint) {
-        let m = Arc::new(Mutex::new());
-        let mut rxs = Vec::new();
-
-        for _ in range(0u, num_waiters) {
-            let mi = m.clone();
-            let (tx, rx) = channel();
-            rxs.push(rx);
-            task::spawn(proc() {
-                let lock = mi.lock();
-                tx.send(());
-                lock.cond.wait();
-                tx.send(());
-            });
-        }
-
-        // wait until all children get in the mutex
-        for rx in rxs.iter_mut() { rx.recv(); }
-        {
-            let lock = m.lock();
-            let num_woken = lock.cond.broadcast();
-            assert_eq!(num_woken, num_waiters);
-        }
-        // wait until all children wake up
-        for rx in rxs.iter_mut() { rx.recv(); }
-    }
-
-    #[test]
-    fn test_mutex_cond_broadcast() {
-        test_mutex_cond_broadcast_helper(12);
-    }
-
-    #[test]
-    fn test_mutex_cond_broadcast_none() {
-        test_mutex_cond_broadcast_helper(0);
-    }
-
-    #[test]
-    fn test_mutex_cond_no_waiter() {
-        let m = Arc::new(Mutex::new());
-        let m2 = m.clone();
-        let _ = task::try(proc() {
-            drop(m.lock());
-        });
-        let lock = m2.lock();
-        assert!(!lock.cond.signal());
-    }
-
-    #[test]
-    fn test_mutex_killed_simple() {
-        use any::Any;
-
-        // Mutex must get automatically unlocked if panicked/killed within.
-        let m = Arc::new(Mutex::new());
-        let m2 = m.clone();
-
-        let result: result::Result<(), Box<Any + Send>> = task::try(proc() {
-            let _lock = m2.lock();
-            panic!();
-        });
-        assert!(result.is_err());
-        // child task must have finished by the time try returns
-        drop(m.lock());
-    }
-
-    #[test]
-    fn test_mutex_cond_signal_on_0() {
-        // Tests that signal_on(0) is equivalent to signal().
-        let m = Arc::new(Mutex::new());
-        let lock = m.lock();
-        let m2 = m.clone();
-        task::spawn(proc() {
-            let lock = m2.lock();
-            lock.cond.signal_on(0);
-        });
-        lock.cond.wait();
-    }
-
-    #[test]
-    fn test_mutex_no_condvars() {
-        let result = task::try(proc() {
-            let m = Mutex::new_with_condvars(0);
-            m.lock().cond.wait();
-        });
-        assert!(result.is_err());
-        let result = task::try(proc() {
-            let m = Mutex::new_with_condvars(0);
-            m.lock().cond.signal();
-        });
-        assert!(result.is_err());
-        let result = task::try(proc() {
-            let m = Mutex::new_with_condvars(0);
-            m.lock().cond.broadcast();
-        });
-        assert!(result.is_err());
-    }
-
-    #[cfg(test)]
-    pub enum RWLockMode { Read, Write, Downgrade, DowngradeRead }
-
-    #[cfg(test)]
-    fn lock_rwlock_in_mode(x: &Arc<RWLock>, mode: RWLockMode, blk: ||) {
-        match mode {
-            Read => { let _g = x.read(); blk() }
-            Write => { let _g = x.write(); blk() }
-            Downgrade => { let _g = x.write(); blk() }
-            DowngradeRead => { let _g = x.write().downgrade(); blk() }
-        }
-    }
-
-    #[cfg(test)]
-    fn test_rwlock_exclusion(x: Arc<RWLock>,
-                             mode1: RWLockMode,
-                             mode2: RWLockMode) {
-        // Test mutual exclusion between readers and writers. Just like the
-        // mutex mutual exclusion test, a ways above.
-        let (tx, rx) = channel();
-        let x2 = x.clone();
-        let mut sharedstate = box 0;
-        {
-            let ptr: *const int = &*sharedstate;
-            task::spawn(proc() {
-                let sharedstate: &mut int =
-                    unsafe { mem::transmute(ptr) };
-                access_shared(sharedstate, &x2, mode1, 10);
-                tx.send(());
-            });
-        }
-        {
-            access_shared(&mut *sharedstate, &x, mode2, 10);
-            let _ = rx.recv();
-
-            assert_eq!(*sharedstate, 20);
-        }
-
-        fn access_shared(sharedstate: &mut int, x: &Arc<RWLock>,
-                         mode: RWLockMode, n: uint) {
-            for _ in range(0u, n) {
-                lock_rwlock_in_mode(x, mode, || {
-                    let oldval = *sharedstate;
-                    task::deschedule();
-                    *sharedstate = oldval + 1;
-                })
-            }
-        }
-    }
-
-    #[test]
-    fn test_rwlock_readers_wont_modify_the_data() {
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Read, Write);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Write, Read);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Read, Downgrade);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Downgrade, Read);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Write, DowngradeRead);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), DowngradeRead, Write);
-    }
-
-    #[test]
-    fn test_rwlock_writers_and_writers() {
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Write, Write);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Write, Downgrade);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Downgrade, Write);
-        test_rwlock_exclusion(Arc::new(RWLock::new()), Downgrade, Downgrade);
-    }
-
-    #[cfg(test)]
-    fn test_rwlock_handshake(x: Arc<RWLock>,
-                             mode1: RWLockMode,
-                             mode2: RWLockMode,
-                             make_mode2_go_first: bool) {
-        // Much like sem_multi_resource.
-        let x2 = x.clone();
-        let (tx1, rx1) = channel();
-        let (tx2, rx2) = channel();
-        task::spawn(proc() {
-            if !make_mode2_go_first {
-                rx2.recv(); // parent sends to us once it locks, or ...
-            }
-            lock_rwlock_in_mode(&x2, mode2, || {
-                if make_mode2_go_first {
-                    tx1.send(()); // ... we send to it once we lock
-                }
-                rx2.recv();
-                tx1.send(());
-            })
-        });
-        if make_mode2_go_first {
-            rx1.recv(); // child sends to us once it locks, or ...
-        }
-        lock_rwlock_in_mode(&x, mode1, || {
-            if !make_mode2_go_first {
-                tx2.send(()); // ... we send to it once we lock
-            }
-            tx2.send(());
-            rx1.recv();
-        })
-    }
-
-    #[test]
-    fn test_rwlock_readers_and_readers() {
-        test_rwlock_handshake(Arc::new(RWLock::new()), Read, Read, false);
-        // The downgrader needs to get in before the reader gets in, otherwise
-        // they cannot end up reading at the same time.
-        test_rwlock_handshake(Arc::new(RWLock::new()), DowngradeRead, Read, false);
-        test_rwlock_handshake(Arc::new(RWLock::new()), Read, DowngradeRead, true);
-        // Two downgrade_reads can never both end up reading at the same time.
-    }
-
-    #[test]
-    fn test_rwlock_downgrade_unlock() {
-        // Tests that downgrade can unlock the lock in both modes
-        let x = Arc::new(RWLock::new());
-        lock_rwlock_in_mode(&x, Downgrade, || { });
-        test_rwlock_handshake(x, Read, Read, false);
-        let y = Arc::new(RWLock::new());
-        lock_rwlock_in_mode(&y, DowngradeRead, || { });
-        test_rwlock_exclusion(y, Write, Write);
-    }
-
-    #[test]
-    fn test_rwlock_read_recursive() {
-        let x = RWLock::new();
-        let _g1 = x.read();
-        let _g2 = x.read();
-    }
-
-    #[test]
-    fn test_rwlock_cond_wait() {
-        // As test_mutex_cond_wait above.
-        let x = Arc::new(RWLock::new());
-
-        // Child wakes up parent
-        {
-            let lock = x.write();
-            let x2 = x.clone();
-            task::spawn(proc() {
-                let lock = x2.write();
-                assert!(lock.cond.signal());
-            });
-            lock.cond.wait();
-        }
-        // Parent wakes up child
-        let (tx, rx) = channel();
-        let x3 = x.clone();
-        task::spawn(proc() {
-            let lock = x3.write();
-            tx.send(());
-            lock.cond.wait();
-            tx.send(());
-        });
-        rx.recv(); // Wait until child gets in the rwlock
-        drop(x.read()); // Must be able to get in as a reader
-        {
-            let x = x.write();
-            assert!(x.cond.signal());
-        }
-        rx.recv(); // Wait until child wakes up
-        drop(x.read()); // Just for good measure
-    }
-
-    #[cfg(test)]
-    fn test_rwlock_cond_broadcast_helper(num_waiters: uint) {
-        // Much like the mutex broadcast test. Downgrade-enabled.
-        fn lock_cond(x: &Arc<RWLock>, blk: |c: &Condvar|) {
-            let lock = x.write();
-            blk(&lock.cond);
-        }
-
-        let x = Arc::new(RWLock::new());
-        let mut rxs = Vec::new();
-
-        for _ in range(0u, num_waiters) {
-            let xi = x.clone();
-            let (tx, rx) = channel();
-            rxs.push(rx);
-            task::spawn(proc() {
-                lock_cond(&xi, |cond| {
-                    tx.send(());
-                    cond.wait();
-                    tx.send(());
-                })
-            });
-        }
-
-        // wait until all children get in the mutex
-        for rx in rxs.iter_mut() { let _ = rx.recv(); }
-        lock_cond(&x, |cond| {
-            let num_woken = cond.broadcast();
-            assert_eq!(num_woken, num_waiters);
-        });
-        // wait until all children wake up
-        for rx in rxs.iter_mut() { let _ = rx.recv(); }
-    }
-
-    #[test]
-    fn test_rwlock_cond_broadcast() {
-        test_rwlock_cond_broadcast_helper(0);
-        test_rwlock_cond_broadcast_helper(12);
-    }
-
-    #[cfg(test)]
-    fn rwlock_kill_helper(mode1: RWLockMode, mode2: RWLockMode) {
-        use any::Any;
-
-        // Mutex must get automatically unlocked if panicked/killed within.
-        let x = Arc::new(RWLock::new());
-        let x2 = x.clone();
-
-        let result: result::Result<(), Box<Any + Send>> = task::try(proc() {
-            lock_rwlock_in_mode(&x2, mode1, || {
-                panic!();
-            })
-        });
-        assert!(result.is_err());
-        // child task must have finished by the time try returns
-        lock_rwlock_in_mode(&x, mode2, || { })
-    }
-
-    #[test]
-    fn test_rwlock_reader_killed_writer() {
-        rwlock_kill_helper(Read, Write);
-    }
-
-    #[test]
-    fn test_rwlock_writer_killed_reader() {
-        rwlock_kill_helper(Write, Read);
-    }
-
-    #[test]
-    fn test_rwlock_reader_killed_reader() {
-        rwlock_kill_helper(Read, Read);
-    }
-
-    #[test]
-    fn test_rwlock_writer_killed_writer() {
-        rwlock_kill_helper(Write, Write);
-    }
-
-    #[test]
-    fn test_rwlock_kill_downgrader() {
-        rwlock_kill_helper(Downgrade, Read);
-        rwlock_kill_helper(Read, Downgrade);
-        rwlock_kill_helper(Downgrade, Write);
-        rwlock_kill_helper(Write, Downgrade);
-        rwlock_kill_helper(DowngradeRead, Read);
-        rwlock_kill_helper(Read, DowngradeRead);
-        rwlock_kill_helper(DowngradeRead, Write);
-        rwlock_kill_helper(Write, DowngradeRead);
-        rwlock_kill_helper(DowngradeRead, Downgrade);
-        rwlock_kill_helper(DowngradeRead, Downgrade);
-        rwlock_kill_helper(Downgrade, DowngradeRead);
-        rwlock_kill_helper(Downgrade, DowngradeRead);
-    }
-}
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
new file mode 100644
index 00000000000..a4f8b1df6af
--- /dev/null
+++ b/src/libstd/sync/rwlock.rs
@@ -0,0 +1,514 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+
+use kinds::marker;
+use cell::UnsafeCell;
+use sys_common::rwlock as sys;
+use sync::poison;
+
+/// A reader-writer lock
+///
+/// This type of lock allows a number of readers or at most one writer at any
+/// point in time. The write portion of this lock typically allows modification
+/// of the underlying data (exclusive access) and the read portion of this lock
+/// typically allows for read-only access (shared access).
+///
+/// The type parameter `T` represents the data that this lock protects. It is
+/// required that `T` satisfies `Send` to be shared across tasks and `Sync` to
+/// allow concurrent access through readers. The RAII guards returned from the
+/// locking methods implement `Deref` (and `DerefMut` for the `write` methods)
+/// to allow access to the contained of the lock.
+///
+/// RWLocks, like Mutexes, will become poisoned on panics. Note, however, that
+/// an RWLock may only be poisoned if a panic occurs while it is locked
+/// exclusively (write mode). If a panic occurs in any reader, then the lock
+/// will not be poisoned.
+///
+/// # Example
+///
+/// ```
+/// use std::sync::RWLock;
+///
+/// let lock = RWLock::new(5i);
+///
+/// // many reader locks can be held at once
+/// {
+///     let r1 = lock.read();
+///     let r2 = lock.read();
+///     assert_eq!(*r1, 5);
+///     assert_eq!(*r2, 5);
+/// } // read locks are dropped at this point
+///
+/// // only one write lock may be held, however
+/// {
+///     let mut w = lock.write();
+///     *w += 1;
+///     assert_eq!(*w, 6);
+/// } // write lock is dropped here
+/// ```
+pub struct RWLock<T> {
+    inner: Box<StaticRWLock>,
+    data: UnsafeCell<T>,
+}
+
+/// Structure representing a staticaly allocated RWLock.
+///
+/// This structure is intended to be used inside of a `static` and will provide
+/// automatic global access as well as lazy initialization. The internal
+/// resources of this RWLock, however, must be manually deallocated.
+///
+/// # Example
+///
+/// ```
+/// use std::sync::{StaticRWLock, RWLOCK_INIT};
+///
+/// static LOCK: StaticRWLock = RWLOCK_INIT;
+///
+/// {
+///     let _g = LOCK.read();
+///     // ... shared read access
+/// }
+/// {
+///     let _g = LOCK.write();
+///     // ... exclusive write access
+/// }
+/// unsafe { LOCK.destroy() } // free all resources
+/// ```
+pub struct StaticRWLock {
+    inner: sys::RWLock,
+    poison: UnsafeCell<poison::Flag>,
+}
+
+/// Constant initialization for a statically-initialized rwlock.
+pub const RWLOCK_INIT: StaticRWLock = StaticRWLock {
+    inner: sys::RWLOCK_INIT,
+    poison: UnsafeCell { value: poison::Flag { failed: false } },
+};
+
+/// RAII structure used to release the shared read access of a lock when
+/// dropped.
+#[must_use]
+pub struct RWLockReadGuard<'a, T: 'a> {
+    __lock: &'a RWLock<T>,
+    __guard: StaticRWLockReadGuard,
+}
+
+/// RAII structure used to release the exclusive write access of a lock when
+/// dropped.
+#[must_use]
+pub struct RWLockWriteGuard<'a, T: 'a> {
+    __lock: &'a RWLock<T>,
+    __guard: StaticRWLockWriteGuard,
+}
+
+/// RAII structure used to release the shared read access of a lock when
+/// dropped.
+#[must_use]
+pub struct StaticRWLockReadGuard {
+    lock: &'static sys::RWLock,
+    marker: marker::NoSend,
+}
+
+/// RAII structure used to release the exclusive write access of a lock when
+/// dropped.
+#[must_use]
+pub struct StaticRWLockWriteGuard {
+    lock: &'static sys::RWLock,
+    marker: marker::NoSend,
+    poison: poison::Guard<'static>,
+}
+
+impl<T: Send + Sync> RWLock<T> {
+    /// Creates a new instance of an RWLock which is unlocked and read to go.
+    pub fn new(t: T) -> RWLock<T> {
+        RWLock { inner: box RWLOCK_INIT, data: UnsafeCell::new(t) }
+    }
+
+    /// Locks this rwlock with shared read access, blocking the current thread
+    /// until it can be acquired.
+    ///
+    /// The calling thread will be blocked until there are no more writers which
+    /// hold the lock. There may be other readers currently inside the lock when
+    /// this method returns. This method does not provide any guarantees with
+    /// respect to the ordering of whether contentious readers or writers will
+    /// acquire the lock first.
+    ///
+    /// Returns an RAII guard which will release this thread's shared access
+    /// once it is dropped.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if the RWLock is poisoned. An RWLock is
+    /// poisoned whenever a writer panics while holding an exclusive lock. The
+    /// panic will occur immediately after the lock has been acquired.
+    #[inline]
+    pub fn read(&self) -> RWLockReadGuard<T> {
+        unsafe {
+            let lock: &'static StaticRWLock = &*(&*self.inner as *const _);
+            RWLockReadGuard::new(self, lock.read())
+        }
+    }
+
+    /// Attempt to acquire this lock with shared read access.
+    ///
+    /// This function will never block and will return immediately if `read`
+    /// would otherwise succeed. Returns `Some` of an RAII guard which will
+    /// release the shared access of this thread when dropped, or `None` if the
+    /// access could not be granted. This method does not provide any
+    /// guarantees with respect to the ordering of whether contentious readers
+    /// or writers will acquire the lock first.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if the RWLock is poisoned. An RWLock is
+    /// poisoned whenever a writer panics while holding an exclusive lock. A
+    /// panic will only occur if the lock is acquired.
+    #[inline]
+    pub fn try_read(&self) -> Option<RWLockReadGuard<T>> {
+        unsafe {
+            let lock: &'static StaticRWLock = &*(&*self.inner as *const _);
+            lock.try_read().map(|guard| {
+                RWLockReadGuard::new(self, guard)
+            })
+        }
+    }
+
+    /// Lock this rwlock with exclusive write access, blocking the current
+    /// thread until it can be acquired.
+    ///
+    /// This function will not return while other writers or other readers
+    /// currently have access to the lock.
+    ///
+    /// Returns an RAII guard which will drop the write access of this rwlock
+    /// when dropped.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if the RWLock is poisoned. An RWLock is
+    /// poisoned whenever a writer panics while holding an exclusive lock. The
+    /// panic will occur when the lock is acquired.
+    #[inline]
+    pub fn write(&self) -> RWLockWriteGuard<T> {
+        unsafe {
+            let lock: &'static StaticRWLock = &*(&*self.inner as *const _);
+            RWLockWriteGuard::new(self, lock.write())
+        }
+    }
+
+    /// Attempt to lock this rwlock with exclusive write access.
+    ///
+    /// This function does not ever block, and it will return `None` if a call
+    /// to `write` would otherwise block. If successful, an RAII guard is
+    /// returned.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if the RWLock is poisoned. An RWLock is
+    /// poisoned whenever a writer panics while holding an exclusive lock. A
+    /// panic will only occur if the lock is acquired.
+    #[inline]
+    pub fn try_write(&self) -> Option<RWLockWriteGuard<T>> {
+        unsafe {
+            let lock: &'static StaticRWLock = &*(&*self.inner as *const _);
+            lock.try_write().map(|guard| {
+                RWLockWriteGuard::new(self, guard)
+            })
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl<T> Drop for RWLock<T> {
+    fn drop(&mut self) {
+        unsafe { self.inner.inner.destroy() }
+    }
+}
+
+impl StaticRWLock {
+    /// Locks this rwlock with shared read access, blocking the current thread
+    /// until it can be acquired.
+    ///
+    /// See `RWLock::read`.
+    #[inline]
+    pub fn read(&'static self) -> StaticRWLockReadGuard {
+        unsafe { self.inner.read() }
+        StaticRWLockReadGuard::new(self)
+    }
+
+    /// Attempt to acquire this lock with shared read access.
+    ///
+    /// See `RWLock::try_read`.
+    #[inline]
+    pub fn try_read(&'static self) -> Option<StaticRWLockReadGuard> {
+        if unsafe { self.inner.try_read() } {
+            Some(StaticRWLockReadGuard::new(self))
+        } else {
+            None
+        }
+    }
+
+    /// Lock this rwlock with exclusive write access, blocking the current
+    /// thread until it can be acquired.
+    ///
+    /// See `RWLock::write`.
+    #[inline]
+    pub fn write(&'static self) -> StaticRWLockWriteGuard {
+        unsafe { self.inner.write() }
+        StaticRWLockWriteGuard::new(self)
+    }
+
+    /// Attempt to lock this rwlock with exclusive write access.
+    ///
+    /// See `RWLock::try_write`.
+    #[inline]
+    pub fn try_write(&'static self) -> Option<StaticRWLockWriteGuard> {
+        if unsafe { self.inner.try_write() } {
+            Some(StaticRWLockWriteGuard::new(self))
+        } else {
+            None
+        }
+    }
+
+    /// Deallocate all resources associated with this static lock.
+    ///
+    /// This method is unsafe to call as there is no guarantee that there are no
+    /// active users of the lock, and this also doesn't prevent any future users
+    /// of this lock. This method is required to be called to not leak memory on
+    /// all platforms.
+    pub unsafe fn destroy(&'static self) {
+        self.inner.destroy()
+    }
+}
+
+impl<'rwlock, T> RWLockReadGuard<'rwlock, T> {
+    fn new(lock: &RWLock<T>, guard: StaticRWLockReadGuard)
+           -> RWLockReadGuard<T> {
+        RWLockReadGuard { __lock: lock, __guard: guard }
+    }
+}
+impl<'rwlock, T> RWLockWriteGuard<'rwlock, T> {
+    fn new(lock: &RWLock<T>, guard: StaticRWLockWriteGuard)
+           -> RWLockWriteGuard<T> {
+        RWLockWriteGuard { __lock: lock, __guard: guard }
+    }
+}
+
+impl<'rwlock, T> Deref<T> for RWLockReadGuard<'rwlock, T> {
+    fn deref(&self) -> &T { unsafe { &*self.__lock.data.get() } }
+}
+impl<'rwlock, T> Deref<T> for RWLockWriteGuard<'rwlock, T> {
+    fn deref(&self) -> &T { unsafe { &*self.__lock.data.get() } }
+}
+impl<'rwlock, T> DerefMut<T> for RWLockWriteGuard<'rwlock, T> {
+    fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.__lock.data.get() } }
+}
+
+impl StaticRWLockReadGuard {
+    fn new(lock: &'static StaticRWLock) -> StaticRWLockReadGuard {
+        let guard = StaticRWLockReadGuard {
+            lock: &lock.inner,
+            marker: marker::NoSend,
+        };
+        unsafe { (*lock.poison.get()).borrow().check("rwlock"); }
+        return guard;
+    }
+}
+impl StaticRWLockWriteGuard {
+    fn new(lock: &'static StaticRWLock) -> StaticRWLockWriteGuard {
+        unsafe {
+            let guard = StaticRWLockWriteGuard {
+                lock: &lock.inner,
+                marker: marker::NoSend,
+                poison: (*lock.poison.get()).borrow(),
+            };
+            guard.poison.check("rwlock");
+            return guard;
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl Drop for StaticRWLockReadGuard {
+    fn drop(&mut self) {
+        unsafe { self.lock.read_unlock(); }
+    }
+}
+
+#[unsafe_destructor]
+impl Drop for StaticRWLockWriteGuard {
+    fn drop(&mut self) {
+        self.poison.done();
+        unsafe { self.lock.write_unlock(); }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+
+    use rand::{mod, Rng};
+    use task;
+    use sync::{Arc, RWLock, StaticRWLock, RWLOCK_INIT};
+
+    #[test]
+    fn smoke() {
+        let l = RWLock::new(());
+        drop(l.read());
+        drop(l.write());
+        drop((l.read(), l.read()));
+        drop(l.write());
+    }
+
+    #[test]
+    fn static_smoke() {
+        static R: StaticRWLock = RWLOCK_INIT;
+        drop(R.read());
+        drop(R.write());
+        drop((R.read(), R.read()));
+        drop(R.write());
+        unsafe { R.destroy(); }
+    }
+
+    #[test]
+    fn frob() {
+        static R: StaticRWLock = RWLOCK_INIT;
+        static N: uint = 10;
+        static M: uint = 1000;
+
+        let (tx, rx) = channel::<()>();
+        for _ in range(0, N) {
+            let tx = tx.clone();
+            spawn(proc() {
+                let mut rng = rand::task_rng();
+                for _ in range(0, M) {
+                    if rng.gen_weighted_bool(N) {
+                        drop(R.write());
+                    } else {
+                        drop(R.read());
+                    }
+                }
+                drop(tx);
+            });
+        }
+        drop(tx);
+        let _ = rx.recv_opt();
+        unsafe { R.destroy(); }
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_rw_arc_poison_wr() {
+        let arc = Arc::new(RWLock::new(1i));
+        let arc2 = arc.clone();
+        let _ = task::try(proc() {
+            let lock = arc2.write();
+            assert_eq!(*lock, 2);
+        });
+        let lock = arc.read();
+        assert_eq!(*lock, 1);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_rw_arc_poison_ww() {
+        let arc = Arc::new(RWLock::new(1i));
+        let arc2 = arc.clone();
+        let _ = task::try(proc() {
+            let lock = arc2.write();
+            assert_eq!(*lock, 2);
+        });
+        let lock = arc.write();
+        assert_eq!(*lock, 1);
+    }
+
+    #[test]
+    fn test_rw_arc_no_poison_rr() {
+        let arc = Arc::new(RWLock::new(1i));
+        let arc2 = arc.clone();
+        let _ = task::try(proc() {
+            let lock = arc2.read();
+            assert_eq!(*lock, 2);
+        });
+        let lock = arc.read();
+        assert_eq!(*lock, 1);
+    }
+    #[test]
+    fn test_rw_arc_no_poison_rw() {
+        let arc = Arc::new(RWLock::new(1i));
+        let arc2 = arc.clone();
+        let _ = task::try(proc() {
+            let lock = arc2.read();
+            assert_eq!(*lock, 2);
+        });
+        let lock = arc.write();
+        assert_eq!(*lock, 1);
+    }
+
+    #[test]
+    fn test_rw_arc() {
+        let arc = Arc::new(RWLock::new(0i));
+        let arc2 = arc.clone();
+        let (tx, rx) = channel();
+
+        task::spawn(proc() {
+            let mut lock = arc2.write();
+            for _ in range(0u, 10) {
+                let tmp = *lock;
+                *lock = -1;
+                task::deschedule();
+                *lock = tmp + 1;
+            }
+            tx.send(());
+        });
+
+        // Readers try to catch the writer in the act
+        let mut children = Vec::new();
+        for _ in range(0u, 5) {
+            let arc3 = arc.clone();
+            children.push(task::try_future(proc() {
+                let lock = arc3.read();
+                assert!(*lock >= 0);
+            }));
+        }
+
+        // Wait for children to pass their asserts
+        for r in children.iter_mut() {
+            assert!(r.get_ref().is_ok());
+        }
+
+        // Wait for writer to finish
+        rx.recv();
+        let lock = arc.read();
+        assert_eq!(*lock, 10);
+    }
+
+    #[test]
+    fn test_rw_arc_access_in_unwind() {
+        let arc = Arc::new(RWLock::new(1i));
+        let arc2 = arc.clone();
+        let _ = task::try::<()>(proc() {
+            struct Unwinder {
+                i: Arc<RWLock<int>>,
+            }
+            impl Drop for Unwinder {
+                fn drop(&mut self) {
+                    let mut lock = self.i.write();
+                    *lock += 1;
+                }
+            }
+            let _u = Unwinder { i: arc2 };
+            panic!();
+        });
+        let lock = arc.read();
+        assert_eq!(*lock, 2);
+    }
+}
diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs
new file mode 100644
index 00000000000..03fb84c38d4
--- /dev/null
+++ b/src/libstd/sync/semaphore.rs
@@ -0,0 +1,195 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use ops::Drop;
+use sync::{Mutex, Condvar};
+
+/// A counting, blocking, semaphore.
+///
+/// Semaphores are a form of atomic counter where access is only granted if the
+/// counter is a positive value. Each acquisition will block the calling thread
+/// until the counter is positive, and each release will increment the counter
+/// and unblock any threads if necessary.
+///
+/// # Example
+///
+/// ```
+/// use std::sync::Semaphore;
+///
+/// // Create a semaphore that represents 5 resources
+/// let sem = Semaphore::new(5);
+///
+/// // Acquire one of the resources
+/// sem.acquire();
+///
+/// // Acquire one of the resources for a limited period of time
+/// {
+///     let _guard = sem.access();
+///     // ...
+/// } // resources is released here
+///
+/// // Release our initially acquired resource
+/// sem.release();
+/// ```
+pub struct Semaphore {
+    lock: Mutex<int>,
+    cvar: Condvar,
+}
+
+/// An RAII guard which will release a resource acquired from a semaphore when
+/// dropped.
+pub struct SemaphoreGuard<'a> {
+    sem: &'a Semaphore,
+}
+
+impl Semaphore {
+    /// Creates a new semaphore with the initial count specified.
+    ///
+    /// The count specified can be thought of as a number of resources, and a
+    /// call to `acquire` or `access` will block until at least one resource is
+    /// available. It is valid to initialize a semaphore with a negative count.
+    pub fn new(count: int) -> Semaphore {
+        Semaphore {
+            lock: Mutex::new(count),
+            cvar: Condvar::new(),
+        }
+    }
+
+    /// Acquires a resource of this semaphore, blocking the current thread until
+    /// it can do so.
+    ///
+    /// This method will block until the internal count of the semaphore is at
+    /// least 1.
+    pub fn acquire(&self) {
+        let mut count = self.lock.lock();
+        while *count <= 0 {
+            self.cvar.wait(&count);
+        }
+        *count -= 1;
+    }
+
+    /// Release a resource from this semaphore.
+    ///
+    /// This will increment the number of resources in this semaphore by 1 and
+    /// will notify any pending waiters in `acquire` or `access` if necessary.
+    pub fn release(&self) {
+        *self.lock.lock() += 1;
+        self.cvar.notify_one();
+    }
+
+    /// Acquires a resource of this semaphore, returning an RAII guard to
+    /// release the semaphore when dropped.
+    ///
+    /// This function is semantically equivalent to an `acquire` followed by a
+    /// `release` when the guard returned is dropped.
+    pub fn access(&self) -> SemaphoreGuard {
+        self.acquire();
+        SemaphoreGuard { sem: self }
+    }
+}
+
+#[unsafe_destructor]
+impl<'a> Drop for SemaphoreGuard<'a> {
+    fn drop(&mut self) {
+        self.sem.release();
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+
+    use sync::Arc;
+    use super::Semaphore;
+
+    #[test]
+    fn test_sem_acquire_release() {
+        let s = Semaphore::new(1);
+        s.acquire();
+        s.release();
+        s.acquire();
+    }
+
+    #[test]
+    fn test_sem_basic() {
+        let s = Semaphore::new(1);
+        let _g = s.access();
+    }
+
+    #[test]
+    fn test_sem_as_mutex() {
+        let s = Arc::new(Semaphore::new(1));
+        let s2 = s.clone();
+        spawn(proc() {
+            let _g = s2.access();
+        });
+        let _g = s.access();
+    }
+
+    #[test]
+    fn test_sem_as_cvar() {
+        /* Child waits and parent signals */
+        let (tx, rx) = channel();
+        let s = Arc::new(Semaphore::new(0));
+        let s2 = s.clone();
+        spawn(proc() {
+            s2.acquire();
+            tx.send(());
+        });
+        s.release();
+        let _ = rx.recv();
+
+        /* Parent waits and child signals */
+        let (tx, rx) = channel();
+        let s = Arc::new(Semaphore::new(0));
+        let s2 = s.clone();
+        spawn(proc() {
+            s2.release();
+            let _ = rx.recv();
+        });
+        s.acquire();
+        tx.send(());
+    }
+
+    #[test]
+    fn test_sem_multi_resource() {
+        // Parent and child both get in the critical section at the same
+        // time, and shake hands.
+        let s = Arc::new(Semaphore::new(2));
+        let s2 = s.clone();
+        let (tx1, rx1) = channel();
+        let (tx2, rx2) = channel();
+        spawn(proc() {
+            let _g = s2.access();
+            let _ = rx2.recv();
+            tx1.send(());
+        });
+        let _g = s.access();
+        tx2.send(());
+        let _ = rx1.recv();
+    }
+
+    #[test]
+    fn test_sem_runtime_friendly_blocking() {
+        let s = Arc::new(Semaphore::new(1));
+        let s2 = s.clone();
+        let (tx, rx) = channel();
+        {
+            let _g = s.access();
+            spawn(proc() {
+                tx.send(());
+                drop(s2.access());
+                tx.send(());
+            });
+            rx.recv(); // wait for child to come alive
+        }
+        rx.recv(); // wait for child to be done
+    }
+}
diff --git a/src/libstd/sys/common/condvar.rs b/src/libstd/sys/common/condvar.rs
new file mode 100644
index 00000000000..e09d9704029
--- /dev/null
+++ b/src/libstd/sys/common/condvar.rs
@@ -0,0 +1,67 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use time::Duration;
+use sys_common::mutex::{mod, Mutex};
+use sys::condvar as imp;
+
+/// An OS-based condition variable.
+///
+/// This structure is the lowest layer possible on top of the OS-provided
+/// condition variables. It is consequently entirely unsafe to use. It is
+/// recommended to use the safer types at the top level of this crate instead of
+/// this type.
+pub struct Condvar(imp::Condvar);
+
+/// Static initializer for condition variables.
+pub const CONDVAR_INIT: Condvar = Condvar(imp::CONDVAR_INIT);
+
+impl Condvar {
+    /// Creates a new condition variable for use.
+    ///
+    /// Behavior is undefined if the condition variable is moved after it is
+    /// first used with any of the functions below.
+    #[inline]
+    pub unsafe fn new() -> Condvar { Condvar(imp::Condvar::new()) }
+
+    /// Signal one waiter on this condition variable to wake up.
+    #[inline]
+    pub unsafe fn notify_one(&self) { self.0.notify_one() }
+
+    /// Awaken all current waiters on this condition variable.
+    #[inline]
+    pub unsafe fn notify_all(&self) { self.0.notify_all() }
+
+    /// Wait for a signal on the specified mutex.
+    ///
+    /// Behavior is undefined if the mutex is not locked by the current thread.
+    /// Behavior is also undefined if more than one mutex is used concurrently
+    /// on this condition variable.
+    #[inline]
+    pub unsafe fn wait(&self, mutex: &Mutex) { self.0.wait(mutex::raw(mutex)) }
+
+    /// Wait for a signal on the specified mutex with a timeout duration
+    /// specified by `dur` (a relative time into the future).
+    ///
+    /// Behavior is undefined if the mutex is not locked by the current thread.
+    /// Behavior is also undefined if more than one mutex is used concurrently
+    /// on this condition variable.
+    #[inline]
+    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        self.0.wait_timeout(mutex::raw(mutex), dur)
+    }
+
+    /// Deallocate all resources associated with this condition variable.
+    ///
+    /// Behavior is undefined if there are current or will be future users of
+    /// this condition variable.
+    #[inline]
+    pub unsafe fn destroy(&self) { self.0.destroy() }
+}
diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs
index 9508d8d9232..c0018c5d970 100644
--- a/src/libstd/sys/common/helper_thread.rs
+++ b/src/libstd/sys/common/helper_thread.rs
@@ -20,13 +20,14 @@
 //! can be created in the future and there must be no active timers at that
 //! time.
 
+use prelude::*;
+
+use cell::UnsafeCell;
 use mem;
 use rustrt::bookkeeping;
-use rustrt::mutex::StaticNativeMutex;
 use rustrt;
-use cell::UnsafeCell;
+use sync::{StaticMutex, StaticCondvar};
 use sys::helper_signal;
-use prelude::*;
 
 use task;
 
@@ -39,7 +40,8 @@ use task;
 /// is for static initialization.
 pub struct Helper<M> {
     /// Internal lock which protects the remaining fields
-    pub lock: StaticNativeMutex,
+    pub lock: StaticMutex,
+    pub cond: StaticCondvar,
 
     // You'll notice that the remaining fields are UnsafeCell<T>, and this is
     // because all helper thread operations are done through &self, but we need
@@ -53,6 +55,9 @@ pub struct Helper<M> {
 
     /// Flag if this helper thread has booted and been initialized yet.
     pub initialized: UnsafeCell<bool>,
+
+    /// Flag if this helper thread has shut down
+    pub shutdown: UnsafeCell<bool>,
 }
 
 impl<M: Send> Helper<M> {
@@ -80,7 +85,9 @@ impl<M: Send> Helper<M> {
                 task::spawn(proc() {
                     bookkeeping::decrement();
                     helper(receive, rx, t);
-                    self.lock.lock().signal()
+                    let _g = self.lock.lock();
+                    *self.shutdown.get() = true;
+                    self.cond.notify_one()
                 });
 
                 rustrt::at_exit(proc() { self.shutdown() });
@@ -119,7 +126,9 @@ impl<M: Send> Helper<M> {
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
 
             // Wait for the child to exit
-            guard.wait();
+            while !*self.shutdown.get() {
+                self.cond.wait(&guard);
+            }
             drop(guard);
 
             // Clean up after ourselves
diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs
index e382ec261a0..f8861c20464 100644
--- a/src/libstd/sys/common/mod.rs
+++ b/src/libstd/sys/common/mod.rs
@@ -19,8 +19,11 @@ use num::Int;
 use path::BytesContainer;
 use collections;
 
-pub mod net;
+pub mod condvar;
 pub mod helper_thread;
+pub mod mutex;
+pub mod net;
+pub mod rwlock;
 pub mod thread_local;
 
 // common error constructors
diff --git a/src/libstd/sys/common/mutex.rs b/src/libstd/sys/common/mutex.rs
new file mode 100644
index 00000000000..117d33db328
--- /dev/null
+++ b/src/libstd/sys/common/mutex.rs
@@ -0,0 +1,64 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub use sys::mutex::raw;
+
+use sys::mutex as imp;
+
+/// An OS-based mutual exclusion lock.
+///
+/// This is the thinnest cross-platform wrapper around OS mutexes. All usage of
+/// this mutex is unsafe and it is recommended to instead use the safe wrapper
+/// at the top level of the crate instead of this type.
+pub struct Mutex(imp::Mutex);
+
+/// Constant initializer for statically allocated mutexes.
+pub const MUTEX_INIT: Mutex = Mutex(imp::MUTEX_INIT);
+
+impl Mutex {
+    /// Creates a newly initialized mutex.
+    ///
+    /// Behavior is undefined if the mutex is moved after the first method is
+    /// called on the mutex.
+    #[inline]
+    pub unsafe fn new() -> Mutex { Mutex(imp::Mutex::new()) }
+
+    /// Lock the mutex blocking the current thread until it is available.
+    ///
+    /// Behavior is undefined if the mutex has been moved between this and any
+    /// previous function call.
+    #[inline]
+    pub unsafe fn lock(&self) { self.0.lock() }
+
+    /// Attempt to lock the mutex without blocking, returning whether it was
+    /// successfully acquired or not.
+    ///
+    /// Behavior is undefined if the mutex has been moved between this and any
+    /// previous function call.
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool { self.0.try_lock() }
+
+    /// Unlock the mutex.
+    ///
+    /// Behavior is undefined if the current thread does not actually hold the
+    /// mutex.
+    #[inline]
+    pub unsafe fn unlock(&self) { self.0.unlock() }
+
+    /// Deallocate all resources associated with this mutex.
+    ///
+    /// Behavior is undefined if there are current or will be future users of
+    /// this mutex.
+    #[inline]
+    pub unsafe fn destroy(&self) { self.0.destroy() }
+}
+
+// not meant to be exported to the outside world, just the containing module
+pub fn raw(mutex: &Mutex) -> &imp::Mutex { &mutex.0 }
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 029fc852742..ddc6dd021c3 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -16,13 +16,13 @@ use libc::{mod, c_char, c_int};
 use mem;
 use num::Int;
 use ptr::{mod, null, null_mut};
-use rustrt::mutex;
 use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
 use io::net::addrinfo;
 use io::{IoResult, IoError};
 use sys::{mod, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
           wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
           decode_error_detailed};
+use sync::{Mutex, MutexGuard};
 use sys_common::{mod, keep_going, short_write, timeout};
 use prelude::*;
 use cmp;
@@ -557,12 +557,12 @@ struct Inner {
 
     // Unused on Linux, where this lock is not necessary.
     #[allow(dead_code)]
-    lock: mutex::NativeMutex
+    lock: Mutex<()>,
 }
 
 impl Inner {
     fn new(fd: sock_t) -> Inner {
-        Inner { fd: fd, lock: unsafe { mutex::NativeMutex::new() } }
+        Inner { fd: fd, lock: Mutex::new(()) }
     }
 }
 
@@ -572,7 +572,7 @@ impl Drop for Inner {
 
 pub struct Guard<'a> {
     pub fd: sock_t,
-    pub guard: mutex::LockGuard<'a>,
+    pub guard: MutexGuard<'a, ()>,
 }
 
 #[unsafe_destructor]
@@ -666,7 +666,7 @@ impl TcpStream {
     fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
         let ret = Guard {
             fd: self.fd(),
-            guard: unsafe { self.inner.lock.lock() },
+            guard: self.inner.lock.lock(),
         };
         assert!(set_nonblocking(self.fd(), true).is_ok());
         ret
@@ -805,7 +805,7 @@ impl UdpSocket {
     fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
         let ret = Guard {
             fd: self.fd(),
-            guard: unsafe { self.inner.lock.lock() },
+            guard: self.inner.lock.lock(),
         };
         assert!(set_nonblocking(self.fd(), true).is_ok());
         ret
diff --git a/src/libstd/sys/common/rwlock.rs b/src/libstd/sys/common/rwlock.rs
new file mode 100644
index 00000000000..df016b9e293
--- /dev/null
+++ b/src/libstd/sys/common/rwlock.rs
@@ -0,0 +1,86 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use sys::rwlock as imp;
+
+/// An OS-based reader-writer lock.
+///
+/// This structure is entirely unsafe and serves as the lowest layer of a
+/// cross-platform binding of system rwlocks. It is recommended to use the
+/// safer types at the top level of this crate instead of this type.
+pub struct RWLock(imp::RWLock);
+
+/// Constant initializer for static RWLocks.
+pub const RWLOCK_INIT: RWLock = RWLock(imp::RWLOCK_INIT);
+
+impl RWLock {
+    /// Creates a new instance of an RWLock.
+    ///
+    /// Usage of an RWLock is undefined if it is moved after its first use (any
+    /// function calls below).
+    #[inline]
+    pub unsafe fn new() -> RWLock { RWLock(imp::RWLock::new()) }
+
+    /// Acquire shared access to the underlying lock, blocking the current
+    /// thread to do so.
+    ///
+    /// Behavior is undefined if the rwlock has been moved between this and any
+    /// previous methodo call.
+    #[inline]
+    pub unsafe fn read(&self) { self.0.read() }
+
+    /// Attempt to acquire shared access to this lock, returning whether it
+    /// succeeded or not.
+    ///
+    /// This function does not block the current thread.
+    ///
+    /// Behavior is undefined if the rwlock has been moved between this and any
+    /// previous methodo call.
+    #[inline]
+    pub unsafe fn try_read(&self) -> bool { self.0.try_read() }
+
+    /// Acquire write access to the underlying lock, blocking the current thread
+    /// to do so.
+    ///
+    /// Behavior is undefined if the rwlock has been moved between this and any
+    /// previous methodo call.
+    #[inline]
+    pub unsafe fn write(&self) { self.0.write() }
+
+    /// Attempt to acquire exclusive access to this lock, returning whether it
+    /// succeeded or not.
+    ///
+    /// This function does not block the current thread.
+    ///
+    /// Behavior is undefined if the rwlock has been moved between this and any
+    /// previous methodo call.
+    #[inline]
+    pub unsafe fn try_write(&self) -> bool { self.0.try_write() }
+
+    /// Unlock previously acquired shared access to this lock.
+    ///
+    /// Behavior is undefined if the current thread does not have shared access.
+    #[inline]
+    pub unsafe fn read_unlock(&self) { self.0.read_unlock() }
+
+    /// Unlock previously acquired exclusive access to this lock.
+    ///
+    /// Behavior is undefined if the current thread does not currently have
+    /// exclusive access.
+    #[inline]
+    pub unsafe fn write_unlock(&self) { self.0.write_unlock() }
+
+    /// Destroy OS-related resources with this RWLock.
+    ///
+    /// Behavior is undefined if there are any currently active users of this
+    /// lock.
+    #[inline]
+    pub unsafe fn destroy(&self) { self.0.destroy() }
+}
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
new file mode 100644
index 00000000000..f64718539ef
--- /dev/null
+++ b/src/libstd/sys/unix/condvar.rs
@@ -0,0 +1,83 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cell::UnsafeCell;
+use libc;
+use sys::mutex::{mod, Mutex};
+use sys::sync as ffi;
+use time::Duration;
+
+pub struct Condvar { inner: UnsafeCell<ffi::pthread_cond_t> }
+
+pub const CONDVAR_INIT: Condvar = Condvar {
+    inner: UnsafeCell { value: ffi::PTHREAD_COND_INITIALIZER },
+};
+
+impl Condvar {
+    #[inline]
+    pub unsafe fn new() -> Condvar {
+        // Might be moved and address is changing it is better to avoid
+        // initialization of potentially opaque OS data before it landed
+        Condvar { inner: UnsafeCell::new(ffi::PTHREAD_COND_INITIALIZER) }
+    }
+
+    #[inline]
+    pub unsafe fn notify_one(&self) {
+        let r = ffi::pthread_cond_signal(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+
+    #[inline]
+    pub unsafe fn notify_all(&self) {
+        let r = ffi::pthread_cond_broadcast(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+
+    #[inline]
+    pub unsafe fn wait(&self, mutex: &Mutex) {
+        let r = ffi::pthread_cond_wait(self.inner.get(), mutex::raw(mutex));
+        debug_assert_eq!(r, 0);
+    }
+
+    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        assert!(dur >= Duration::nanoseconds(0));
+
+        // First, figure out what time it currently is
+        let mut tv = libc::timeval { tv_sec: 0, tv_usec: 0 };
+        let r = ffi::gettimeofday(&mut tv, 0 as *mut _);
+        debug_assert_eq!(r, 0);
+
+        // Offset that time with the specified duration
+        let abs = Duration::seconds(tv.tv_sec as i64) +
+                  Duration::microseconds(tv.tv_usec as i64) +
+                  dur;
+        let ns = abs.num_nanoseconds().unwrap() as u64;
+        let timeout = libc::timespec {
+            tv_sec: (ns / 1000000000) as libc::time_t,
+            tv_nsec: (ns % 1000000000) as libc::c_long,
+        };
+
+        // And wait!
+        let r = ffi::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
+                                            &timeout);
+        if r != 0 {
+            debug_assert_eq!(r as int, libc::ETIMEDOUT as int);
+            false
+        } else {
+            true
+        }
+    }
+
+    #[inline]
+    pub unsafe fn destroy(&self) {
+        let r = ffi::pthread_cond_destroy(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+}
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 4b47b768d60..a773ef7e317 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -20,7 +20,7 @@ use prelude::*;
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
 use io::{IoResult, FileStat, SeekStyle, Reader};
 use io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
-use result::{Ok, Err};
+use result::Result::{Ok, Err};
 use sys::retry;
 use sys_common::{keep_going, eof, mkerr_libc};
 
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index af238905119..4effedbe3ab 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -25,23 +25,29 @@ use sys_common::mkerr_libc;
 
 macro_rules! helper_init( (static $name:ident: Helper<$m:ty>) => (
     static $name: Helper<$m> = Helper {
-        lock: ::rustrt::mutex::NATIVE_MUTEX_INIT,
+        lock: ::sync::MUTEX_INIT,
+        cond: ::sync::CONDVAR_INIT,
         chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
         signal: ::cell::UnsafeCell { value: 0 },
         initialized: ::cell::UnsafeCell { value: false },
+        shutdown: ::cell::UnsafeCell { value: false },
     };
 ) )
 
 pub mod c;
 pub mod ext;
+pub mod condvar;
 pub mod fs;
 pub mod helper_signal;
+pub mod mutex;
 pub mod os;
 pub mod pipe;
 pub mod process;
+pub mod rwlock;
+pub mod sync;
 pub mod tcp;
-pub mod timer;
 pub mod thread_local;
+pub mod timer;
 pub mod tty;
 pub mod udp;
 
diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs
new file mode 100644
index 00000000000..2f01c53cb2c
--- /dev/null
+++ b/src/libstd/sys/unix/mutex.rs
@@ -0,0 +1,52 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cell::UnsafeCell;
+use sys::sync as ffi;
+use sys_common::mutex;
+
+pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
+
+#[inline]
+pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t {
+    m.inner.get()
+}
+
+pub const MUTEX_INIT: Mutex = Mutex {
+    inner: UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER },
+};
+
+impl Mutex {
+    #[inline]
+    pub unsafe fn new() -> Mutex {
+        // Might be moved and address is changing it is better to avoid
+        // initialization of potentially opaque OS data before it landed
+        MUTEX_INIT
+    }
+    #[inline]
+    pub unsafe fn lock(&self) {
+        let r = ffi::pthread_mutex_lock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        let r = ffi::pthread_mutex_unlock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        ffi::pthread_mutex_trylock(self.inner.get()) == 0
+    }
+    #[inline]
+    pub unsafe fn destroy(&self) {
+        let r = ffi::pthread_mutex_destroy(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+}
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 3f70fb5c1a5..08e6f7059d8 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -12,8 +12,7 @@ use alloc::arc::Arc;
 use libc;
 use c_str::CString;
 use mem;
-use rustrt::mutex;
-use sync::atomic;
+use sync::{atomic, Mutex};
 use io::{mod, IoResult, IoError};
 use prelude::*;
 
@@ -60,12 +59,12 @@ struct Inner {
 
     // Unused on Linux, where this lock is not necessary.
     #[allow(dead_code)]
-    lock: mutex::NativeMutex
+    lock: Mutex<()>,
 }
 
 impl Inner {
     fn new(fd: fd_t) -> Inner {
-        Inner { fd: fd, lock: unsafe { mutex::NativeMutex::new() } }
+        Inner { fd: fd, lock: Mutex::new(()) }
     }
 }
 
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index 76c316076f9..7dde19a6476 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -11,7 +11,7 @@ use self::Req::*;
 
 use libc::{mod, pid_t, c_void, c_int};
 use c_str::CString;
-use io::{mod, IoResult, IoError};
+use io::{mod, IoResult, IoError, EndOfFile};
 use mem;
 use os;
 use ptr;
@@ -39,6 +39,8 @@ enum Req {
     NewChild(libc::pid_t, Sender<ProcessExit>, u64),
 }
 
+const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
+
 impl Process {
     pub fn id(&self) -> pid_t {
         self.pid
@@ -106,18 +108,36 @@ impl Process {
                 if pid < 0 {
                     return Err(super::last_error())
                 } else if pid > 0 {
+                    #[inline]
+                    fn combine(arr: &[u8]) -> i32 {
+                        let a = arr[0] as u32;
+                        let b = arr[1] as u32;
+                        let c = arr[2] as u32;
+                        let d = arr[3] as u32;
+
+                        ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32
+                    }
+
+                    let p = Process{ pid: pid };
                     drop(output);
-                    let mut bytes = [0, ..4];
+                    let mut bytes = [0, ..8];
                     return match input.read(&mut bytes) {
-                        Ok(4) => {
-                            let errno = (bytes[0] as i32 << 24) |
-                                        (bytes[1] as i32 << 16) |
-                                        (bytes[2] as i32 <<  8) |
-                                        (bytes[3] as i32 <<  0);
+                        Ok(8) => {
+                            assert!(combine(CLOEXEC_MSG_FOOTER) == combine(bytes.slice(4, 8)),
+                                "Validation on the CLOEXEC pipe failed: {}", bytes);
+                            let errno = combine(bytes.slice(0, 4));
+                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
                             Err(super::decode_error(errno))
                         }
-                        Err(..) => Ok(Process { pid: pid }),
-                        Ok(..) => panic!("short read on the cloexec pipe"),
+                        Err(ref e) if e.kind == EndOfFile => Ok(p),
+                        Err(e) => {
+                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
+                            panic!("the CLOEXEC pipe failed: {}", e)
+                        },
+                        Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic
+                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
+                            panic!("short read on the CLOEXEC pipe")
+                        }
                     };
                 }
 
@@ -154,13 +174,16 @@ impl Process {
                 let _ = libc::close(input.fd());
 
                 fn fail(output: &mut FileDesc) -> ! {
-                    let errno = sys::os::errno();
+                    let errno = sys::os::errno() as u32;
                     let bytes = [
                         (errno >> 24) as u8,
                         (errno >> 16) as u8,
                         (errno >>  8) as u8,
                         (errno >>  0) as u8,
+                        CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1],
+                        CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3]
                     ];
+                    // pipe I/O up to PIPE_BUF bytes should be atomic
                     assert!(output.write(&bytes).is_ok());
                     unsafe { libc::_exit(1) }
                 }
diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs
new file mode 100644
index 00000000000..0d63ff14ff2
--- /dev/null
+++ b/src/libstd/sys/unix/rwlock.rs
@@ -0,0 +1,57 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cell::UnsafeCell;
+use sys::sync as ffi;
+
+pub struct RWLock { inner: UnsafeCell<ffi::pthread_rwlock_t> }
+
+pub const RWLOCK_INIT: RWLock = RWLock {
+    inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER },
+};
+
+impl RWLock {
+    #[inline]
+    pub unsafe fn new() -> RWLock {
+        // Might be moved and address is changing it is better to avoid
+        // initialization of potentially opaque OS data before it landed
+        RWLOCK_INIT
+    }
+    #[inline]
+    pub unsafe fn read(&self) {
+        let r = ffi::pthread_rwlock_rdlock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn try_read(&self) -> bool {
+        ffi::pthread_rwlock_tryrdlock(self.inner.get()) == 0
+    }
+    #[inline]
+    pub unsafe fn write(&self) {
+        let r = ffi::pthread_rwlock_wrlock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn try_write(&self) -> bool {
+        ffi::pthread_rwlock_trywrlock(self.inner.get()) == 0
+    }
+    #[inline]
+    pub unsafe fn read_unlock(&self) {
+        let r = ffi::pthread_rwlock_unlock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn write_unlock(&self) { self.read_unlock() }
+    #[inline]
+    pub unsafe fn destroy(&self) {
+        let r = ffi::pthread_rwlock_destroy(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+}
diff --git a/src/libstd/sys/unix/sync.rs b/src/libstd/sys/unix/sync.rs
new file mode 100644
index 00000000000..007826b4b9d
--- /dev/null
+++ b/src/libstd/sys/unix/sync.rs
@@ -0,0 +1,208 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(bad_style)]
+
+use libc;
+
+pub use self::os::{PTHREAD_MUTEX_INITIALIZER, pthread_mutex_t};
+pub use self::os::{PTHREAD_COND_INITIALIZER, pthread_cond_t};
+pub use self::os::{PTHREAD_RWLOCK_INITIALIZER, pthread_rwlock_t};
+
+extern {
+    // mutexes
+    pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> libc::c_int;
+    pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> libc::c_int;
+    pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> libc::c_int;
+    pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> libc::c_int;
+
+    // cvars
+    pub fn pthread_cond_wait(cond: *mut pthread_cond_t,
+                             lock: *mut pthread_mutex_t) -> libc::c_int;
+    pub fn pthread_cond_timedwait(cond: *mut pthread_cond_t,
+                              lock: *mut pthread_mutex_t,
+                              abstime: *const libc::timespec) -> libc::c_int;
+    pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> libc::c_int;
+    pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> libc::c_int;
+    pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> libc::c_int;
+    pub fn gettimeofday(tp: *mut libc::timeval,
+                        tz: *mut libc::c_void) -> libc::c_int;
+
+    // rwlocks
+    pub fn pthread_rwlock_destroy(lock: *mut pthread_rwlock_t) -> libc::c_int;
+    pub fn pthread_rwlock_rdlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
+    pub fn pthread_rwlock_tryrdlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
+    pub fn pthread_rwlock_wrlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
+    pub fn pthread_rwlock_trywrlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
+    pub fn pthread_rwlock_unlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
+}
+
+#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+mod os {
+    use libc;
+
+    pub type pthread_mutex_t = *mut libc::c_void;
+    pub type pthread_cond_t = *mut libc::c_void;
+    pub type pthread_rwlock_t = *mut libc::c_void;
+
+    pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 0 as *mut _;
+    pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _;
+    pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 0 as *mut _;
+}
+
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+mod os {
+    use libc;
+
+    #[cfg(target_arch = "x86_64")]
+    const __PTHREAD_MUTEX_SIZE__: uint = 56;
+    #[cfg(any(target_arch = "x86",
+              target_arch = "arm"))]
+    const __PTHREAD_MUTEX_SIZE__: uint = 40;
+
+    #[cfg(target_arch = "x86_64")]
+    const __PTHREAD_COND_SIZE__: uint = 40;
+    #[cfg(any(target_arch = "x86",
+              target_arch = "arm"))]
+    const __PTHREAD_COND_SIZE__: uint = 24;
+
+    #[cfg(target_arch = "x86_64")]
+    const __PTHREAD_RWLOCK_SIZE__: uint = 192;
+    #[cfg(any(target_arch = "x86",
+              target_arch = "arm"))]
+    const __PTHREAD_RWLOCK_SIZE__: uint = 124;
+
+    const _PTHREAD_MUTEX_SIG_INIT: libc::c_long = 0x32AAABA7;
+    const _PTHREAD_COND_SIG_INIT: libc::c_long = 0x3CB0B1BB;
+    const _PTHREAD_RWLOCK_SIG_INIT: libc::c_long = 0x2DA8B3B4;
+
+    #[repr(C)]
+    pub struct pthread_mutex_t {
+        __sig: libc::c_long,
+        __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
+    }
+    #[repr(C)]
+    pub struct pthread_cond_t {
+        __sig: libc::c_long,
+        __opaque: [u8, ..__PTHREAD_COND_SIZE__],
+    }
+    #[repr(C)]
+    pub struct pthread_rwlock_t {
+        __sig: libc::c_long,
+        __opaque: [u8, ..__PTHREAD_RWLOCK_SIZE__],
+    }
+
+    pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
+        __sig: _PTHREAD_MUTEX_SIG_INIT,
+        __opaque: [0, ..__PTHREAD_MUTEX_SIZE__],
+    };
+    pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
+        __sig: _PTHREAD_COND_SIG_INIT,
+        __opaque: [0, ..__PTHREAD_COND_SIZE__],
+    };
+    pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
+        __sig: _PTHREAD_RWLOCK_SIG_INIT,
+        __opaque: [0, ..__PTHREAD_RWLOCK_SIZE__],
+    };
+}
+
+#[cfg(target_os = "linux")]
+mod os {
+    use libc;
+
+    // minus 8 because we have an 'align' field
+    #[cfg(target_arch = "x86_64")]
+    const __SIZEOF_PTHREAD_MUTEX_T: uint = 40 - 8;
+    #[cfg(any(target_arch = "x86",
+              target_arch = "arm",
+              target_arch = "mips",
+              target_arch = "mipsel"))]
+    const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
+
+    #[cfg(any(target_arch = "x86_64",
+              target_arch = "x86",
+              target_arch = "arm",
+              target_arch = "mips",
+              target_arch = "mipsel"))]
+    const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
+
+    #[cfg(target_arch = "x86_64")]
+    const __SIZEOF_PTHREAD_RWLOCK_T: uint = 56 - 8;
+
+    #[cfg(any(target_arch = "x86",
+              target_arch = "arm",
+              target_arch = "mips",
+              target_arch = "mipsel"))]
+    const __SIZEOF_PTHREAD_RWLOCK_T: uint = 32 - 8;
+
+    #[repr(C)]
+    pub struct pthread_mutex_t {
+        __align: libc::c_longlong,
+        size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
+    }
+    #[repr(C)]
+    pub struct pthread_cond_t {
+        __align: libc::c_longlong,
+        size: [u8, ..__SIZEOF_PTHREAD_COND_T],
+    }
+    #[repr(C)]
+    pub struct pthread_rwlock_t {
+        __align: libc::c_longlong,
+        size: [u8, ..__SIZEOF_PTHREAD_RWLOCK_T],
+    }
+
+    pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
+        __align: 0,
+        size: [0, ..__SIZEOF_PTHREAD_MUTEX_T],
+    };
+    pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
+        __align: 0,
+        size: [0, ..__SIZEOF_PTHREAD_COND_T],
+    };
+    pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
+        __align: 0,
+        size: [0, ..__SIZEOF_PTHREAD_RWLOCK_T],
+    };
+}
+#[cfg(target_os = "android")]
+mod os {
+    use libc;
+
+    #[repr(C)]
+    pub struct pthread_mutex_t { value: libc::c_int }
+    #[repr(C)]
+    pub struct pthread_cond_t { value: libc::c_int }
+    #[repr(C)]
+    pub struct pthread_rwlock_t {
+        lock: pthread_mutex_t,
+        cond: pthread_cond_t,
+        numLocks: libc::c_int,
+        writerThreadId: libc::c_int,
+        pendingReaders: libc::c_int,
+        pendingWriters: libc::c_int,
+        reserved: [*mut libc::c_void, ..4],
+    }
+
+    pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
+        value: 0,
+    };
+    pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
+        value: 0,
+    };
+    pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
+        lock: PTHREAD_MUTEX_INITIALIZER,
+        cond: PTHREAD_COND_INITIALIZER,
+        numLocks: 0,
+        writerThreadId: 0,
+        pendingReaders: 0,
+        pendingWriters: 0,
+        reserved: [0 as *mut _, ..4],
+    };
+}
diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs
new file mode 100644
index 00000000000..3cabf3a6319
--- /dev/null
+++ b/src/libstd/sys/windows/condvar.rs
@@ -0,0 +1,63 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cell::UnsafeCell;
+use libc::{mod, DWORD};
+use libc;
+use os;
+use sys::mutex::{mod, Mutex};
+use sys::sync as ffi;
+use time::Duration;
+
+pub struct Condvar { inner: UnsafeCell<ffi::CONDITION_VARIABLE> }
+
+pub const CONDVAR_INIT: Condvar = Condvar {
+    inner: UnsafeCell { value: ffi::CONDITION_VARIABLE_INIT }
+};
+
+impl Condvar {
+    #[inline]
+    pub unsafe fn new() -> Condvar { CONDVAR_INIT }
+
+    #[inline]
+    pub unsafe fn wait(&self, mutex: &Mutex) {
+        let r = ffi::SleepConditionVariableCS(self.inner.get(),
+                                              mutex::raw(mutex),
+                                              libc::INFINITE);
+        debug_assert!(r != 0);
+    }
+
+    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        let r = ffi::SleepConditionVariableCS(self.inner.get(),
+                                              mutex::raw(mutex),
+                                              dur.num_milliseconds() as DWORD);
+        if r == 0 {
+            const ERROR_TIMEOUT: DWORD = 0x5B4;
+            debug_assert_eq!(os::errno() as uint, ERROR_TIMEOUT as uint);
+            false
+        } else {
+            true
+        }
+    }
+
+    #[inline]
+    pub unsafe fn notify_one(&self) {
+        ffi::WakeConditionVariable(self.inner.get())
+    }
+
+    #[inline]
+    pub unsafe fn notify_all(&self) {
+        ffi::WakeAllConditionVariable(self.inner.get())
+    }
+
+    pub unsafe fn destroy(&self) {
+        // ...
+    }
+}
diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs
index 2c58ee69e8b..049aca3f590 100644
--- a/src/libstd/sys/windows/ext.rs
+++ b/src/libstd/sys/windows/ext.rs
@@ -76,13 +76,13 @@ impl AsRawSocket for io::net::tcp::TcpStream {
 
 impl AsRawSocket for io::net::tcp::TcpListener {
     fn as_raw_socket(&self) -> Socket {
-        self.as_inner().fd()
+        self.as_inner().socket()
     }
 }
 
 impl AsRawSocket for io::net::tcp::TcpAcceptor {
     fn as_raw_socket(&self) -> Socket {
-        self.as_inner().fd()
+        self.as_inner().socket()
     }
 }
 
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 9c4ffb926b5..9402c63dcf5 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -131,7 +131,7 @@ impl FileDesc {
         return ret;
     }
 
-    pub fn fstat(&mut self) -> IoResult<io::FileStat> {
+    pub fn fstat(&self) -> IoResult<io::FileStat> {
         let mut stat: libc::stat = unsafe { mem::zeroed() };
         match unsafe { libc::fstat(self.fd(), &mut stat) } {
             0 => Ok(mkstat(&stat)),
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 6b9555c52ce..9fce308cb94 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -26,20 +26,26 @@ use sync::{Once, ONCE_INIT};
 
 macro_rules! helper_init( (static $name:ident: Helper<$m:ty>) => (
     static $name: Helper<$m> = Helper {
-        lock: ::rustrt::mutex::NATIVE_MUTEX_INIT,
+        lock: ::sync::MUTEX_INIT,
+        cond: ::sync::CONDVAR_INIT,
         chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
         signal: ::cell::UnsafeCell { value: 0 },
         initialized: ::cell::UnsafeCell { value: false },
+        shutdown: ::cell::UnsafeCell { value: false },
     };
 ) )
 
 pub mod c;
 pub mod ext;
+pub mod condvar;
 pub mod fs;
 pub mod helper_signal;
+pub mod mutex;
 pub mod os;
 pub mod pipe;
 pub mod process;
+pub mod rwlock;
+pub mod sync;
 pub mod tcp;
 pub mod thread_local;
 pub mod timer;
diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs
new file mode 100644
index 00000000000..ddd89070ed5
--- /dev/null
+++ b/src/libstd/sys/windows/mutex.rs
@@ -0,0 +1,78 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+
+use sync::atomic;
+use alloc::{mod, heap};
+
+use libc::DWORD;
+use sys::sync as ffi;
+
+const SPIN_COUNT: DWORD = 4000;
+
+pub struct Mutex { inner: atomic::AtomicUint }
+
+pub const MUTEX_INIT: Mutex = Mutex { inner: atomic::INIT_ATOMIC_UINT };
+
+#[inline]
+pub unsafe fn raw(m: &Mutex) -> ffi::LPCRITICAL_SECTION {
+    m.get()
+}
+
+impl Mutex {
+    #[inline]
+    pub unsafe fn new() -> Mutex {
+        Mutex { inner: atomic::AtomicUint::new(init_lock() as uint) }
+    }
+    #[inline]
+    pub unsafe fn lock(&self) {
+        ffi::EnterCriticalSection(self.get())
+    }
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        ffi::TryEnterCriticalSection(self.get()) != 0
+    }
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        ffi::LeaveCriticalSection(self.get())
+    }
+    pub unsafe fn destroy(&self) {
+        let lock = self.inner.swap(0, atomic::SeqCst);
+        if lock != 0 { free_lock(lock as ffi::LPCRITICAL_SECTION) }
+    }
+
+    unsafe fn get(&self) -> ffi::LPCRITICAL_SECTION {
+        match self.inner.load(atomic::SeqCst) {
+            0 => {}
+            n => return n as ffi::LPCRITICAL_SECTION
+        }
+        let lock = init_lock();
+        match self.inner.compare_and_swap(0, lock as uint, atomic::SeqCst) {
+            0 => return lock as ffi::LPCRITICAL_SECTION,
+            _ => {}
+        }
+        free_lock(lock);
+        return self.inner.load(atomic::SeqCst) as ffi::LPCRITICAL_SECTION;
+    }
+}
+
+unsafe fn init_lock() -> ffi::LPCRITICAL_SECTION {
+    let block = heap::allocate(ffi::CRITICAL_SECTION_SIZE, 8)
+                        as ffi::LPCRITICAL_SECTION;
+    if block.is_null() { alloc::oom() }
+    ffi::InitializeCriticalSectionAndSpinCount(block, SPIN_COUNT);
+    return block;
+}
+
+unsafe fn free_lock(h: ffi::LPCRITICAL_SECTION) {
+    ffi::DeleteCriticalSection(h);
+    heap::deallocate(h as *mut _, ffi::CRITICAL_SECTION_SIZE, 8);
+}
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index ca7985aa35b..bf658d0efd0 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -89,8 +89,7 @@ use libc;
 use c_str::CString;
 use mem;
 use ptr;
-use sync::atomic;
-use rustrt::mutex;
+use sync::{atomic, Mutex};
 use io::{mod, IoError, IoResult};
 use prelude::*;
 
@@ -126,7 +125,7 @@ impl Drop for Event {
 
 struct Inner {
     handle: libc::HANDLE,
-    lock: mutex::NativeMutex,
+    lock: Mutex<()>,
     read_closed: atomic::AtomicBool,
     write_closed: atomic::AtomicBool,
 }
@@ -135,7 +134,7 @@ impl Inner {
     fn new(handle: libc::HANDLE) -> Inner {
         Inner {
             handle: handle,
-            lock: unsafe { mutex::NativeMutex::new() },
+            lock: Mutex::new(()),
             read_closed: atomic::AtomicBool::new(false),
             write_closed: atomic::AtomicBool::new(false),
         }
diff --git a/src/libstd/sys/windows/rwlock.rs b/src/libstd/sys/windows/rwlock.rs
new file mode 100644
index 00000000000..88ce85c39f6
--- /dev/null
+++ b/src/libstd/sys/windows/rwlock.rs
@@ -0,0 +1,53 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cell::UnsafeCell;
+use sys::sync as ffi;
+
+pub struct RWLock { inner: UnsafeCell<ffi::SRWLOCK> }
+
+pub const RWLOCK_INIT: RWLock = RWLock {
+    inner: UnsafeCell { value: ffi::SRWLOCK_INIT }
+};
+
+impl RWLock {
+    #[inline]
+    pub unsafe fn new() -> RWLock { RWLOCK_INIT }
+
+    #[inline]
+    pub unsafe fn read(&self) {
+        ffi::AcquireSRWLockShared(self.inner.get())
+    }
+    #[inline]
+    pub unsafe fn try_read(&self) -> bool {
+        ffi::TryAcquireSRWLockShared(self.inner.get()) != 0
+    }
+    #[inline]
+    pub unsafe fn write(&self) {
+        ffi::AcquireSRWLockExclusive(self.inner.get())
+    }
+    #[inline]
+    pub unsafe fn try_write(&self) -> bool {
+        ffi::TryAcquireSRWLockExclusive(self.inner.get()) != 0
+    }
+    #[inline]
+    pub unsafe fn read_unlock(&self) {
+        ffi::ReleaseSRWLockShared(self.inner.get())
+    }
+    #[inline]
+    pub unsafe fn write_unlock(&self) {
+        ffi::ReleaseSRWLockExclusive(self.inner.get())
+    }
+
+    #[inline]
+    pub unsafe fn destroy(&self) {
+        // ...
+    }
+}
diff --git a/src/libstd/sys/windows/sync.rs b/src/libstd/sys/windows/sync.rs
new file mode 100644
index 00000000000..cbca47912b5
--- /dev/null
+++ b/src/libstd/sys/windows/sync.rs
@@ -0,0 +1,58 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use libc::{BOOL, DWORD, c_void, LPVOID};
+use libc::types::os::arch::extra::BOOLEAN;
+
+pub type LPCRITICAL_SECTION = *mut c_void;
+pub type LPCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
+pub type LPSRWLOCK = *mut SRWLOCK;
+
+#[cfg(target_arch = "x86")]
+pub const CRITICAL_SECTION_SIZE: uint = 24;
+#[cfg(target_arch = "x86_64")]
+pub const CRITICAL_SECTION_SIZE: uint = 40;
+
+#[repr(C)]
+pub struct CONDITION_VARIABLE { pub ptr: LPVOID }
+#[repr(C)]
+pub struct SRWLOCK { pub ptr: LPVOID }
+
+pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE {
+    ptr: 0 as *mut _,
+};
+pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: 0 as *mut _ };
+
+extern "system" {
+    // critical sections
+    pub fn InitializeCriticalSectionAndSpinCount(
+                    lpCriticalSection: LPCRITICAL_SECTION,
+                    dwSpinCount: DWORD) -> BOOL;
+    pub fn DeleteCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
+    pub fn EnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
+    pub fn LeaveCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
+    pub fn TryEnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION) -> BOOL;
+
+    // condition variables
+    pub fn SleepConditionVariableCS(ConditionVariable: LPCONDITION_VARIABLE,
+                                    CriticalSection: LPCRITICAL_SECTION,
+                                    dwMilliseconds: DWORD) -> BOOL;
+    pub fn WakeConditionVariable(ConditionVariable: LPCONDITION_VARIABLE);
+    pub fn WakeAllConditionVariable(ConditionVariable: LPCONDITION_VARIABLE);
+
+    // slim rwlocks
+    pub fn AcquireSRWLockExclusive(SRWLock: LPSRWLOCK);
+    pub fn AcquireSRWLockShared(SRWLock: LPSRWLOCK);
+    pub fn ReleaseSRWLockExclusive(SRWLock: LPSRWLOCK);
+    pub fn ReleaseSRWLockShared(SRWLock: LPSRWLOCK);
+    pub fn TryAcquireSRWLockExclusive(SRWLock: LPSRWLOCK) -> BOOLEAN;
+    pub fn TryAcquireSRWLockShared(SRWLock: LPSRWLOCK) -> BOOLEAN;
+}
+
diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs
index 3baf2be08d2..b577372d2fc 100644
--- a/src/libstd/sys/windows/tcp.rs
+++ b/src/libstd/sys/windows/tcp.rs
@@ -48,37 +48,35 @@ impl Drop for Event {
 // TCP listeners
 ////////////////////////////////////////////////////////////////////////////////
 
-pub struct TcpListener {
-    inner: FileDesc,
-}
+pub struct TcpListener { sock: sock_t }
 
 impl TcpListener {
     pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
         sys::init_net();
 
-        let fd = try!(socket(addr, libc::SOCK_STREAM));
-        let ret = TcpListener { inner: FileDesc::new(fd as libc::c_int, true) };
+        let sock = try!(socket(addr, libc::SOCK_STREAM));
+        let ret = TcpListener { sock: sock };
 
         let mut storage = unsafe { mem::zeroed() };
         let len = addr_to_sockaddr(addr, &mut storage);
         let addrp = &storage as *const _ as *const libc::sockaddr;
 
-        match unsafe { libc::bind(fd, addrp, len) } {
+        match unsafe { libc::bind(sock, addrp, len) } {
             -1 => Err(last_net_error()),
             _ => Ok(ret),
         }
     }
 
-    pub fn fd(&self) -> sock_t { self.inner.fd as sock_t }
+    pub fn socket(&self) -> sock_t { self.sock }
 
     pub fn listen(self, backlog: int) -> IoResult<TcpAcceptor> {
-        match unsafe { libc::listen(self.fd(), backlog as libc::c_int) } {
+        match unsafe { libc::listen(self.socket(), backlog as libc::c_int) } {
             -1 => Err(last_net_error()),
 
             _ => {
                 let accept = try!(Event::new());
                 let ret = unsafe {
-                    c::WSAEventSelect(self.fd(), accept.handle(), c::FD_ACCEPT)
+                    c::WSAEventSelect(self.socket(), accept.handle(), c::FD_ACCEPT)
                 };
                 if ret != 0 {
                     return Err(last_net_error())
@@ -97,7 +95,13 @@ impl TcpListener {
     }
 
     pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        sockname(self.fd(), libc::getsockname)
+        sockname(self.socket(), libc::getsockname)
+    }
+}
+
+impl Drop for TcpListener {
+    fn drop(&mut self) {
+        unsafe { super::close_sock(self.sock); }
     }
 }
 
@@ -114,7 +118,7 @@ struct AcceptorInner {
 }
 
 impl TcpAcceptor {
-    pub fn fd(&self) -> sock_t { self.inner.listener.fd() }
+    pub fn socket(&self) -> sock_t { self.inner.listener.socket() }
 
     pub fn accept(&mut self) -> IoResult<TcpStream> {
         // Unlink unix, windows cannot invoke `select` on arbitrary file
@@ -161,13 +165,13 @@ impl TcpAcceptor {
 
             let mut wsaevents: c::WSANETWORKEVENTS = unsafe { mem::zeroed() };
             let ret = unsafe {
-                c::WSAEnumNetworkEvents(self.fd(), events[1], &mut wsaevents)
+                c::WSAEnumNetworkEvents(self.socket(), events[1], &mut wsaevents)
             };
             if ret != 0 { return Err(last_net_error()) }
 
             if wsaevents.lNetworkEvents & c::FD_ACCEPT == 0 { continue }
             match unsafe {
-                libc::accept(self.fd(), ptr::null_mut(), ptr::null_mut())
+                libc::accept(self.socket(), ptr::null_mut(), ptr::null_mut())
             } {
                 -1 if wouldblock() => {}
                 -1 => return Err(last_net_error()),
@@ -175,13 +179,13 @@ impl TcpAcceptor {
                 // Accepted sockets inherit the same properties as the caller,
                 // so we need to deregister our event and switch the socket back
                 // to blocking mode
-                fd => {
-                    let stream = TcpStream::new(fd);
+                socket => {
+                    let stream = TcpStream::new(socket);
                     let ret = unsafe {
-                        c::WSAEventSelect(fd, events[1], 0)
+                        c::WSAEventSelect(socket, events[1], 0)
                     };
                     if ret != 0 { return Err(last_net_error()) }
-                    try!(set_nonblocking(fd, false));
+                    try!(set_nonblocking(socket, false));
                     return Ok(stream)
                 }
             }
@@ -191,7 +195,7 @@ impl TcpAcceptor {
     }
 
     pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        sockname(self.fd(), libc::getsockname)
+        sockname(self.socket(), libc::getsockname)
     }
 
     pub fn set_timeout(&mut self, timeout: Option<u64>) {
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index a0ee08570d9..8b4dbf61c18 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -49,7 +49,8 @@ use boxed::Box;
 use comm::channel;
 use io::{Writer, stdio};
 use kinds::{Send, marker};
-use option::{None, Some, Option};
+use option::Option;
+use option::Option::{None, Some};
 use result::Result;
 use rustrt::local::Local;
 use rustrt::task::Task;
@@ -172,9 +173,10 @@ impl TaskBuilder {
     /// # Return value
     ///
     /// If the child task executes successfully (without panicking) then the
-    /// future returns `result::Ok` containing the value returned by the
-    /// function. If the child task panics then the future returns `result::Err`
-    /// containing the argument to `panic!(...)` as an `Any` trait object.
+    /// future returns `result::Result::Ok` containing the value returned by the
+    /// function. If the child task panics then the future returns
+    /// `result::Result::Err` containing the argument to `panic!(...)` as an
+    /// `Any` trait object.
     #[experimental = "Futures are experimental."]
     pub fn try_future<T:Send>(self, f: proc():Send -> T)
                               -> Future<Result<T, Box<Any + Send>>> {
@@ -268,7 +270,7 @@ mod test {
     use borrow::IntoCow;
     use boxed::BoxAny;
     use prelude::*;
-    use result::{Ok, Err};
+    use result::Result::{Ok, Err};
     use result;
     use std::io::{ChanReader, ChanWriter};
     use string::String;
@@ -330,7 +332,7 @@ mod test {
         match try(proc() {
             "Success!".to_string()
         }).as_ref().map(|s| s.as_slice()) {
-            result::Ok("Success!") => (),
+            result::Result::Ok("Success!") => (),
             _ => panic!()
         }
     }
@@ -340,8 +342,8 @@ mod test {
         match try(proc() {
             panic!()
         }) {
-            result::Err(_) => (),
-            result::Ok(()) => panic!()
+            result::Result::Err(_) => (),
+            result::Result::Ok(()) => panic!()
         }
     }
 
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index e2e8461ea54..029b8bf1138 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -115,7 +115,7 @@ macro_rules! thread_local(
             use std::cell::UnsafeCell as __UnsafeCell;
             use std::thread_local::KeyInner as __KeyInner;
             use std::option::Option as __Option;
-            use std::option::None as __None;
+            use std::option::Option::None as __None;
 
             __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
                 __UnsafeCell { value: __None }
@@ -132,7 +132,7 @@ macro_rules! thread_local(
             use std::cell::UnsafeCell as __UnsafeCell;
             use std::thread_local::KeyInner as __KeyInner;
             use std::option::Option as __Option;
-            use std::option::None as __None;
+            use std::option::Option::None as __None;
 
             __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
                 __UnsafeCell { value: __None }
@@ -198,7 +198,7 @@ macro_rules! __thread_local_inner(
                 inner: ::std::cell::UnsafeCell { value: $init },
                 os: ::std::thread_local::OsStaticKey {
                     inner: ::std::thread_local::OS_INIT_INNER,
-                    dtor: ::std::option::Some(__destroy),
+                    dtor: ::std::option::Option::Some(__destroy),
                 },
             }
         };
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index ec2d62ff85c..63eb9a98736 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -14,9 +14,11 @@
 
 use {fmt, i64};
 use ops::{Add, Sub, Mul, Div, Neg};
-use option::{Option, Some, None};
+use option::Option;
+use option::Option::{Some, None};
 use num::Int;
-use result::{Result, Ok, Err};
+use result::Result;
+use result::Result::{Ok, Err};
 
 /// The number of nanoseconds in a microsecond.
 const NANOS_PER_MICRO: i32 = 1000;
@@ -387,7 +389,7 @@ fn div_rem_64(this: i64, other: i64) -> (i64, i64) {
 mod tests {
     use super::{Duration, MIN, MAX};
     use {i32, i64};
-    use option::{Some, None};
+    use option::Option::{Some, None};
     use string::ToString;
 
     #[test]
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 5f4e675aad5..2be11a236d3 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -45,15 +45,6 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
         [ast::TtToken(_, token::Ident(code, _))] => code,
         _ => unreachable!()
     };
-    with_registered_diagnostics(|diagnostics| {
-        if !diagnostics.contains_key(&code.name) {
-            ecx.span_err(span, format!(
-                "unknown diagnostic code {}; add to librustc/diagnostics.rs",
-                token::get_ident(code).get()
-            ).as_slice());
-        }
-        ()
-    });
     with_used_diagnostics(|diagnostics| {
         match diagnostics.insert(code.name, span) {
             Some(previous_span) => {
@@ -106,25 +97,19 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
         _ => unreachable!()
     };
 
-    let (count, expr) = with_used_diagnostics(|diagnostics_in_use| {
+    let (count, expr) =
         with_registered_diagnostics(|diagnostics| {
-            let descriptions: Vec<P<ast::Expr>> = diagnostics
-                .iter().filter_map(|(code, description)| {
-                if !diagnostics_in_use.contains_key(code) {
-                    ecx.span_warn(span, format!(
-                        "diagnostic code {} never used", token::get_name(*code).get()
-                    ).as_slice());
-                }
-                description.map(|description| {
-                    ecx.expr_tuple(span, vec![
-                        ecx.expr_str(span, token::get_name(*code)),
-                        ecx.expr_str(span, token::get_name(description))
-                    ])
-                })
-            }).collect();
+            let descriptions: Vec<P<ast::Expr>> =
+                diagnostics.iter().filter_map(|(code, description)| {
+                    description.map(|description| {
+                        ecx.expr_tuple(span, vec![
+                            ecx.expr_str(span, token::get_name(*code)),
+                            ecx.expr_str(span, token::get_name(description))])
+                    })
+                }).collect();
             (descriptions.len(), ecx.expr_vec(span, descriptions))
-        })
-    });
+        });
+
     MacItems::new(vec![quote_item!(ecx,
         pub static $name: [(&'static str, &'static str), ..$count] = $expr;
     ).unwrap()].into_iter())
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index bd01e5e6430..b4bb1a1a529 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -680,6 +680,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let some = vec!(
             self.ident_of("std"),
             self.ident_of("option"),
+            self.ident_of("Option"),
             self.ident_of("Some"));
         self.expr_call_global(sp, some, vec!(expr))
     }
@@ -688,6 +689,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let none = self.path_global(sp, vec!(
             self.ident_of("std"),
             self.ident_of("option"),
+            self.ident_of("Option"),
             self.ident_of("None")));
         self.expr_path(none)
     }
@@ -732,6 +734,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let ok = vec!(
             self.ident_of("std"),
             self.ident_of("result"),
+            self.ident_of("Result"),
             self.ident_of("Ok"));
         self.expr_call_global(sp, ok, vec!(expr))
     }
@@ -740,6 +743,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let err = vec!(
             self.ident_of("std"),
             self.ident_of("result"),
+            self.ident_of("Result"),
             self.ident_of("Err"));
         self.expr_call_global(sp, err, vec!(expr))
     }
@@ -810,6 +814,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let some = vec!(
             self.ident_of("std"),
             self.ident_of("option"),
+            self.ident_of("Option"),
             self.ident_of("Some"));
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!(pat))
@@ -819,6 +824,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let some = vec!(
             self.ident_of("std"),
             self.ident_of("option"),
+            self.ident_of("Option"),
             self.ident_of("None"));
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!())
@@ -828,6 +834,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let some = vec!(
             self.ident_of("std"),
             self.ident_of("result"),
+            self.ident_of("Result"),
             self.ident_of("Ok"));
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!(pat))
@@ -837,6 +844,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let some = vec!(
             self.ident_of("std"),
             self.ident_of("result"),
+            self.ident_of("Result"),
             self.ident_of("Err"));
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!(pat))
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 98345e1dd67..787c6e844d5 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -105,6 +105,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
     let ordering = cx.path_global(span,
                                   vec!(cx.ident_of("std"),
                                        cx.ident_of("cmp"),
+                                       cx.ident_of("Ordering"),
                                        cx.ident_of("Equal")));
     let ordering = cx.expr_path(ordering);
     let equals_expr = cx.expr_some(span, ordering);
@@ -120,9 +121,9 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
     Builds:
 
     let __test = ::std::cmp::PartialOrd::partial_cmp(&self_field1, &other_field1);
-    if __test == ::std::option::Some(::std::cmp::Equal) {
+    if __test == ::std::option::Option::Some(::std::cmp::Ordering::Equal) {
         let __test = ::std::cmp::PartialOrd::partial_cmp(&self_field2, &other_field2);
-        if __test == ::std::option::Some(::std::cmp::Equal) {
+        if __test == ::std::option::Option::Some(::std::cmp::Ordering::Equal) {
             ...
         } else {
             __test
@@ -139,7 +140,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
         false,
         |cx, span, old, self_f, other_fs| {
             // let __test = new;
-            // if __test == Some(::std::cmp::Equal) {
+            // if __test == Some(::std::cmp::Ordering::Equal) {
             //    old
             // } else {
             //    __test
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index d84ad677e5d..83af45462ec 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -70,9 +70,9 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
     Builds:
 
     let __test = self_field1.cmp(&other_field2);
-    if other == ::std::cmp::Equal {
+    if other == ::std::cmp::Ordering::Equal {
         let __test = self_field2.cmp(&other_field2);
-        if __test == ::std::cmp::Equal {
+        if __test == ::std::cmp::Ordering::Equal {
             ...
         } else {
             __test
@@ -89,7 +89,7 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
         false,
         |cx, span, old, new| {
             // let __test = new;
-            // if __test == ::std::cmp::Equal {
+            // if __test == ::std::cmp::Ordering::Equal {
             //    old
             // } else {
             //    __test
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 87e257c52cd..e6a44c57f1b 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -36,6 +36,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
                                    true,
                                    vec!(cx.ident_of("std"),
                                         cx.ident_of("option"),
+                                        cx.ident_of("Option"),
                                         cx.ident_of("None")),
                                    Vec::new(),
                                    vec!(cx.ty_rptr(sp,
@@ -50,6 +51,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
           cx.expr_call_global(sp,
                               vec!(cx.ident_of("std"),
                                    cx.ident_of("option"),
+                                   cx.ident_of("Option"),
                                    cx.ident_of("Some")),
                               vec!(cx.expr_str(sp,
                                                token::intern_and_get_ident(
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 3fca110a881..45752499ad5 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -450,9 +450,8 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
                        sp: Span,
                        tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'static> {
-    let e_param_colons = cx.expr_lit(sp, ast::LitBool(false));
     let expanded = expand_parse_call(cx, sp, "parse_ty",
-                                     vec!(e_param_colons), tts);
+                                     vec![], tts);
     base::MacExpr::new(expanded)
 }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index c7aef0020b2..11c65d531f6 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -32,9 +32,7 @@ use parse::token;
 
 use std::slice;
 
-/// This is a list of all known features since the beginning of time. This list
-/// can never shrink, it may only be expanded (in order to prevent old programs
-/// from failing to compile). The status of each feature may change, however.
+// if you change this list without updating src/doc/reference.md, @cmr will be sad
 static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
     ("globs", Active),
     ("macro_rules", Active),
@@ -65,15 +63,13 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
     ("unboxed_closures", Active),
     ("import_shadowing", Active),
     ("advanced_slice_patterns", Active),
-    ("tuple_indexing", Active),
+    ("tuple_indexing", Accepted),
     ("associated_types", Active),
     ("visible_private_types", Active),
     ("slicing_syntax", Active),
 
-    ("if_let", Active),
-    ("while_let", Active),
-
-    // if you change this list without updating src/doc/reference.md, cmr will be sad
+    ("if_let", Accepted),
+    ("while_let", Accepted),
 
     // A temporary feature gate used to enable parser extensions needed
     // to bootstrap fix for #5723.
@@ -309,24 +305,11 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
                                   "unboxed closures are a work-in-progress \
                                    feature with known bugs");
             }
-            ast::ExprTupField(..) => {
-                self.gate_feature("tuple_indexing",
-                                  e.span,
-                                  "tuple indexing is experimental");
-            }
-            ast::ExprIfLet(..) => {
-                self.gate_feature("if_let", e.span,
-                                  "`if let` syntax is experimental");
-            }
             ast::ExprSlice(..) => {
                 self.gate_feature("slicing_syntax",
                                   e.span,
                                   "slicing syntax is experimental");
             }
-            ast::ExprWhileLet(..) => {
-                self.gate_feature("while_let", e.span,
-                                  "`while let` syntax is experimental");
-            }
             _ => {}
         }
         visit::walk_expr(self, e);
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index db7bc6c323f..41fee1556ab 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -212,7 +212,7 @@ impl<'a> ParserAttr for Parser<'a> {
     fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
         self.parse_seq(&token::OpenDelim(token::Paren),
                        &token::CloseDelim(token::Paren),
-                       seq_sep_trailing_disallowed(token::Comma),
+                       seq_sep_trailing_allowed(token::Comma),
                        |p| p.parse_meta_item()).node
     }
 
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
index 3842170d677..a96bf1ce10b 100644
--- a/src/libsyntax/parse/common.rs
+++ b/src/libsyntax/parse/common.rs
@@ -19,18 +19,13 @@ pub struct SeqSep {
     pub trailing_sep_allowed: bool
 }
 
-pub fn seq_sep_trailing_disallowed(t: token::Token) -> SeqSep {
-    SeqSep {
-        sep: Some(t),
-        trailing_sep_allowed: false,
-    }
-}
 pub fn seq_sep_trailing_allowed(t: token::Token) -> SeqSep {
     SeqSep {
         sep: Some(t),
         trailing_sep_allowed: true,
     }
 }
+
 pub fn seq_sep_none() -> SeqSep {
     SeqSep {
         sep: None,
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 57983a6dee6..b282db5ba2b 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -764,6 +764,15 @@ impl<'a> StringReader<'a> {
         }
     }
 
+    // SNAP 361baab
+    #[allow(unused)]
+    fn old_escape_warning(&mut self, sp: Span) {
+        self.span_diagnostic
+            .span_warn(sp, "\\U00ABCD12 and \\uABCD escapes are deprecated");
+        self.span_diagnostic
+            .span_help(sp, "use \\u{ABCD12} escapes instead");
+    }
+
     /// Scan for a single (possibly escaped) byte or char
     /// in a byte, (non-raw) byte string, char, or (non-raw) string literal.
     /// `start` is the position of `first_source_char`, which is already consumed.
@@ -782,12 +791,24 @@ impl<'a> StringReader<'a> {
                     Some(e) => {
                         return match e {
                             'n' | 'r' | 't' | '\\' | '\'' | '"' | '0' => true,
-                            'x' => self.scan_hex_digits(2u, delim, !ascii_only),
+                            'x' => self.scan_byte_escape(delim, !ascii_only),
                             'u' if !ascii_only => {
-                                self.scan_hex_digits(4u, delim, false)
+                                if self.curr == Some('{') {
+                                    self.scan_unicode_escape(delim)
+                                } else {
+                                    let res = self.scan_hex_digits(4u, delim, false);
+                                    // SNAP 361baab
+                                    //let sp = codemap::mk_sp(escaped_pos, self.last_pos);
+                                    //self.old_escape_warning(sp);
+                                    res
+                                }
                             }
                             'U' if !ascii_only => {
-                                self.scan_hex_digits(8u, delim, false)
+                                let res = self.scan_hex_digits(8u, delim, false);
+                                // SNAP 361baab
+                                //let sp = codemap::mk_sp(escaped_pos, self.last_pos);
+                                //self.old_escape_warning(sp);
+                                res
                             }
                             '\n' if delim == '"' => {
                                 self.consume_whitespace();
@@ -848,6 +869,56 @@ impl<'a> StringReader<'a> {
         true
     }
 
+    /// Scan over a \u{...} escape
+    ///
+    /// At this point, we have already seen the \ and the u, the { is the current character. We
+    /// will read at least one digit, and up to 6, and pass over the }.
+    fn scan_unicode_escape(&mut self, delim: char) -> bool {
+        self.bump(); // past the {
+        let start_bpos = self.last_pos;
+        let mut count: uint = 0;
+        let mut accum_int = 0;
+
+        while !self.curr_is('}') && count <= 6 {
+            let c = match self.curr {
+                Some(c) => c,
+                None => {
+                    self.fatal_span_(start_bpos, self.last_pos,
+                                     "unterminated unicode escape (found EOF)");
+                }
+            };
+            accum_int *= 16;
+            accum_int += c.to_digit(16).unwrap_or_else(|| {
+                if c == delim {
+                    self.fatal_span_(self.last_pos, self.pos,
+                                     "unterminated unicode escape (needed a `}`)");
+                } else {
+                    self.fatal_span_char(self.last_pos, self.pos,
+                                   "illegal character in unicode escape", c);
+                }
+            }) as u32;
+            self.bump();
+            count += 1;
+        }
+
+        if count > 6 {
+            self.fatal_span_(start_bpos, self.last_pos,
+                          "overlong unicode escape (can have at most 6 hex digits)");
+        }
+
+        self.bump(); // past the ending }
+
+        let mut valid = count >= 1 && count <= 6;
+        if char::from_u32(accum_int).is_none() {
+            valid = false;
+        }
+
+        if !valid {
+            self.fatal_span_(start_bpos, self.last_pos, "illegal unicode character escape");
+        }
+        valid
+    }
+
     /// Scan over a float exponent.
     fn scan_float_exponent(&mut self) {
         if self.curr_is('e') || self.curr_is('E') {
@@ -1273,6 +1344,10 @@ impl<'a> StringReader<'a> {
         return token::Byte(id);
     }
 
+    fn scan_byte_escape(&mut self, delim: char, below_0x7f_only: bool) -> bool {
+        self.scan_hex_digits(2, delim, below_0x7f_only)
+    }
+
     fn scan_byte_string(&mut self) -> token::Lit {
         self.bump();
         let start = self.last_pos;
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b46f7cdfe22..8d0c2de048a 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -393,16 +393,28 @@ pub fn char_lit(lit: &str) -> (char, int) {
     let msg = format!("lexer should have rejected a bad character escape {}", lit);
     let msg2 = msg.as_slice();
 
-    let esc: |uint| -> Option<(char, int)> = |len|
+    fn esc(len: uint, lit: &str) -> Option<(char, int)> {
         num::from_str_radix(lit.slice(2, len), 16)
         .and_then(char::from_u32)
-        .map(|x| (x, len as int));
+        .map(|x| (x, len as int))
+    }
+
+    let unicode_escape: || -> Option<(char, int)> = ||
+        if lit.as_bytes()[2] == b'{' {
+            let idx = lit.find('}').expect(msg2);
+            let subslice = lit.slice(3, idx);
+            num::from_str_radix(subslice, 16)
+                .and_then(char::from_u32)
+                .map(|x| (x, subslice.char_len() as int + 4))
+        } else {
+            esc(6, lit)
+        };
 
     // Unicode escapes
     return match lit.as_bytes()[1] as char {
-        'x' | 'X' => esc(4),
-        'u' => esc(6),
-        'U' => esc(10),
+        'x' | 'X' => esc(4, lit),
+        'u' => unicode_escape(),
+        'U' => esc(10, lit),
         _ => None,
     }.expect(msg2);
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 920bcc3a951..bb3d28ce2bb 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -87,6 +87,7 @@ use std::mem;
 use std::num::Float;
 use std::rc::Rc;
 use std::iter;
+use std::slice;
 
 bitflags! {
     flags Restrictions: u8 {
@@ -303,6 +304,22 @@ pub struct Parser<'a> {
     /// name is not known. This does not change while the parser is descending
     /// into modules, and sub-parsers have new values for this name.
     pub root_module_name: Option<String>,
+    pub expected_tokens: Vec<TokenType>,
+}
+
+#[deriving(PartialEq, Eq, Clone)]
+pub enum TokenType {
+    Token(token::Token),
+    Operator,
+}
+
+impl TokenType {
+    fn to_string(&self) -> String {
+        match *self {
+            TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)),
+            TokenType::Operator => "an operator".into_string(),
+        }
+    }
 }
 
 fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
@@ -347,6 +364,7 @@ impl<'a> Parser<'a> {
             open_braces: Vec::new(),
             owns_directory: true,
             root_module_name: None,
+            expected_tokens: Vec::new(),
         }
     }
 
@@ -375,14 +393,18 @@ impl<'a> Parser<'a> {
     /// Expect and consume the token t. Signal an error if
     /// the next token is not t.
     pub fn expect(&mut self, t: &token::Token) {
-        if self.token == *t {
-            self.bump();
+        if self.expected_tokens.is_empty() {
+            if self.token == *t {
+                self.bump();
+            } else {
+                let token_str = Parser::token_to_string(t);
+                let this_token_str = self.this_token_to_string();
+                self.fatal(format!("expected `{}`, found `{}`",
+                                   token_str,
+                                   this_token_str).as_slice())
+            }
         } else {
-            let token_str = Parser::token_to_string(t);
-            let this_token_str = self.this_token_to_string();
-            self.fatal(format!("expected `{}`, found `{}`",
-                               token_str,
-                               this_token_str).as_slice())
+            self.expect_one_of(slice::ref_slice(t), &[]);
         }
     }
 
@@ -392,15 +414,20 @@ impl<'a> Parser<'a> {
     pub fn expect_one_of(&mut self,
                          edible: &[token::Token],
                          inedible: &[token::Token]) {
-        fn tokens_to_string(tokens: &[token::Token]) -> String {
+        fn tokens_to_string(tokens: &[TokenType]) -> String {
             let mut i = tokens.iter();
             // This might be a sign we need a connect method on Iterator.
             let b = i.next()
-                     .map_or("".to_string(), |t| Parser::token_to_string(t));
-            i.fold(b, |b,a| {
-                let mut b = b;
-                b.push_str("`, `");
-                b.push_str(Parser::token_to_string(a).as_slice());
+                     .map_or("".into_string(), |t| t.to_string());
+            i.enumerate().fold(b, |mut b, (i, ref a)| {
+                if tokens.len() > 2 && i == tokens.len() - 2 {
+                    b.push_str(", or ");
+                } else if tokens.len() == 2 && i == tokens.len() - 2 {
+                    b.push_str(" or ");
+                } else {
+                    b.push_str(", ");
+                }
+                b.push_str(&*a.to_string());
                 b
             })
         }
@@ -409,17 +436,21 @@ impl<'a> Parser<'a> {
         } else if inedible.contains(&self.token) {
             // leave it in the input
         } else {
-            let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
-            expected.push_all(inedible);
+            let mut expected = edible.iter().map(|x| TokenType::Token(x.clone()))
+                                            .collect::<Vec<_>>();
+            expected.extend(inedible.iter().map(|x| TokenType::Token(x.clone())));
+            expected.push_all(&*self.expected_tokens);
+            expected.sort_by(|a, b| a.to_string().cmp(&b.to_string()));
+            expected.dedup();
             let expect = tokens_to_string(expected.as_slice());
             let actual = self.this_token_to_string();
             self.fatal(
                 (if expected.len() != 1 {
-                    (format!("expected one of `{}`, found `{}`",
+                    (format!("expected one of {}, found `{}`",
                              expect,
                              actual))
                 } else {
-                    (format!("expected `{}`, found `{}`",
+                    (format!("expected {}, found `{}`",
                              expect,
                              actual))
                 }).as_slice()
@@ -514,10 +545,20 @@ impl<'a> Parser<'a> {
         spanned(lo, hi, node)
     }
 
+    /// Check if the next token is `tok`, and return `true` if so.
+    ///
+    /// This method is will automatically add `tok` to `expected_tokens` if `tok` is not
+    /// encountered.
+    pub fn check(&mut self, tok: &token::Token) -> bool {
+        let is_present = self.token == *tok;
+        if !is_present { self.expected_tokens.push(TokenType::Token(tok.clone())); }
+        is_present
+    }
+
     /// Consume token 'tok' if it exists. Returns true if the given
     /// token was present, false otherwise.
     pub fn eat(&mut self, tok: &token::Token) -> bool {
-        let is_present = self.token == *tok;
+        let is_present = self.check(tok);
         if is_present { self.bump() }
         is_present
     }
@@ -739,7 +780,7 @@ impl<'a> Parser<'a> {
         // commas in generic parameters, because it can stop either after
         // parsing a type or after parsing a comma.
         for i in iter::count(0u, 1) {
-            if self.token == token::Gt
+            if self.check(&token::Gt)
                 || self.token == token::BinOp(token::Shr)
                 || self.token == token::Ge
                 || self.token == token::BinOpEq(token::Shr) {
@@ -798,7 +839,7 @@ impl<'a> Parser<'a> {
               }
               _ => ()
             }
-            if sep.trailing_sep_allowed && self.token == *ket { break; }
+            if sep.trailing_sep_allowed && self.check(ket) { break; }
             v.push(f(self));
         }
         return v;
@@ -881,6 +922,7 @@ impl<'a> Parser<'a> {
         self.span = next.sp;
         self.token = next.tok;
         self.tokens_consumed += 1u;
+        self.expected_tokens.clear();
     }
 
     /// Advance the parser by one token and return the bumped token.
@@ -999,7 +1041,7 @@ impl<'a> Parser<'a> {
             self.parse_proc_type(lifetime_defs)
         } else if self.token_is_bare_fn_keyword() || self.token_is_closure_keyword() {
             self.parse_ty_bare_fn_or_ty_closure(lifetime_defs)
-        } else if self.token == token::ModSep ||
+        } else if self.check(&token::ModSep) ||
                   self.token.is_ident() ||
                   self.token.is_path()
         {
@@ -1101,7 +1143,7 @@ impl<'a> Parser<'a> {
     /// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`).
     pub fn parse_optional_unboxed_closure_kind(&mut self)
                                                -> Option<UnboxedClosureKind> {
-        if self.token == token::BinOp(token::And) &&
+        if self.check(&token::BinOp(token::And)) &&
                 self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
                 self.look_ahead(2, |t| *t == token::Colon) {
             self.bump();
@@ -1211,7 +1253,8 @@ impl<'a> Parser<'a> {
                                   lifetime_defs: Vec<ast::LifetimeDef>)
                                   -> Vec<ast::LifetimeDef>
     {
-        if self.eat(&token::Lt) {
+        if self.token == token::Lt {
+            self.bump();
             if lifetime_defs.is_empty() {
                 self.warn("deprecated syntax; use the `for` keyword now \
                             (e.g. change `fn<'a>` to `for<'a> fn`)");
@@ -1430,7 +1473,7 @@ impl<'a> Parser<'a> {
 
         let lo = self.span.lo;
 
-        let t = if self.token == token::OpenDelim(token::Paren) {
+        let t = if self.check(&token::OpenDelim(token::Paren)) {
             self.bump();
 
             // (t) is a parenthesized ty
@@ -1440,7 +1483,7 @@ impl<'a> Parser<'a> {
             let mut last_comma = false;
             while self.token != token::CloseDelim(token::Paren) {
                 ts.push(self.parse_ty_sum());
-                if self.token == token::Comma {
+                if self.check(&token::Comma) {
                     last_comma = true;
                     self.bump();
                 } else {
@@ -1464,11 +1507,11 @@ impl<'a> Parser<'a> {
                 _ => self.obsolete(last_span, ObsoleteOwnedType)
             }
             TyTup(vec![self.parse_ty()])
-        } else if self.token == token::BinOp(token::Star) {
+        } else if self.check(&token::BinOp(token::Star)) {
             // STAR POINTER (bare pointer?)
             self.bump();
             TyPtr(self.parse_ptr())
-        } else if self.token == token::OpenDelim(token::Bracket) {
+        } else if self.check(&token::OpenDelim(token::Bracket)) {
             // VECTOR
             self.expect(&token::OpenDelim(token::Bracket));
             let t = self.parse_ty_sum();
@@ -1481,7 +1524,7 @@ impl<'a> Parser<'a> {
             };
             self.expect(&token::CloseDelim(token::Bracket));
             t
-        } else if self.token == token::BinOp(token::And) ||
+        } else if self.check(&token::BinOp(token::And)) ||
                   self.token == token::AndAnd {
             // BORROWED POINTER
             self.expect_and();
@@ -1492,7 +1535,7 @@ impl<'a> Parser<'a> {
                   self.token_is_closure_keyword() {
             // BARE FUNCTION OR CLOSURE
             self.parse_ty_bare_fn_or_ty_closure(Vec::new())
-        } else if self.token == token::BinOp(token::Or) ||
+        } else if self.check(&token::BinOp(token::Or)) ||
                   self.token == token::OrOr ||
                   (self.token == token::Lt &&
                    self.look_ahead(1, |t| {
@@ -1509,7 +1552,7 @@ impl<'a> Parser<'a> {
             TyTypeof(e)
         } else if self.eat_keyword(keywords::Proc) {
             self.parse_proc_type(Vec::new())
-        } else if self.token == token::Lt {
+        } else if self.check(&token::Lt) {
             // QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
             self.bump();
             let self_type = self.parse_ty_sum();
@@ -1523,7 +1566,7 @@ impl<'a> Parser<'a> {
                 trait_ref: P(trait_ref),
                 item_name: item_name,
             }))
-        } else if self.token == token::ModSep ||
+        } else if self.check(&token::ModSep) ||
                   self.token.is_ident() ||
                   self.token.is_path() {
             // NAMED TYPE
@@ -1532,7 +1575,8 @@ impl<'a> Parser<'a> {
             // TYPE TO BE INFERRED
             TyInfer
         } else {
-            let msg = format!("expected type, found token {}", self.token);
+            let this_token_str = self.this_token_to_string();
+            let msg = format!("expected type, found `{}`", this_token_str);
             self.fatal(msg.as_slice());
         };
 
@@ -1635,7 +1679,7 @@ impl<'a> Parser<'a> {
     }
 
     pub fn maybe_parse_fixed_vstore(&mut self) -> Option<P<ast::Expr>> {
-        if self.token == token::Comma &&
+        if self.check(&token::Comma) &&
                 self.look_ahead(1, |t| *t == token::DotDot) {
             self.bump();
             self.bump();
@@ -1959,9 +2003,10 @@ impl<'a> Parser<'a> {
                 token::Gt => { return res; }
                 token::BinOp(token::Shr) => { return res; }
                 _ => {
+                    let this_token_str = self.this_token_to_string();
                     let msg = format!("expected `,` or `>` after lifetime \
-                                      name, got: {}",
-                                      self.token);
+                                      name, found `{}`",
+                                      this_token_str);
                     self.fatal(msg.as_slice());
                 }
             }
@@ -2126,7 +2171,7 @@ impl<'a> Parser<'a> {
                     es.push(self.parse_expr());
                     self.commit_expr(&**es.last().unwrap(), &[],
                                      &[token::Comma, token::CloseDelim(token::Paren)]);
-                    if self.token == token::Comma {
+                    if self.check(&token::Comma) {
                         trailing_comma = true;
 
                         self.bump();
@@ -2167,14 +2212,14 @@ impl<'a> Parser<'a> {
             token::OpenDelim(token::Bracket) => {
                 self.bump();
 
-                if self.token == token::CloseDelim(token::Bracket) {
+                if self.check(&token::CloseDelim(token::Bracket)) {
                     // Empty vector.
                     self.bump();
                     ex = ExprVec(Vec::new());
                 } else {
                     // Nonempty vector.
                     let first_expr = self.parse_expr();
-                    if self.token == token::Comma &&
+                    if self.check(&token::Comma) &&
                         self.look_ahead(1, |t| *t == token::DotDot) {
                         // Repeating vector syntax: [ 0, ..512 ]
                         self.bump();
@@ -2182,7 +2227,7 @@ impl<'a> Parser<'a> {
                         let count = self.parse_expr();
                         self.expect(&token::CloseDelim(token::Bracket));
                         ex = ExprRepeat(first_expr, count);
-                    } else if self.token == token::Comma {
+                    } else if self.check(&token::Comma) {
                         // Vector with two or more elements.
                         self.bump();
                         let remaining_exprs = self.parse_seq_to_end(
@@ -2284,7 +2329,7 @@ impl<'a> Parser<'a> {
                         ex = ExprBreak(None);
                     }
                     hi = self.span.hi;
-                } else if self.token == token::ModSep ||
+                } else if self.check(&token::ModSep) ||
                         self.token.is_ident() &&
                         !self.token.is_keyword(keywords::True) &&
                         !self.token.is_keyword(keywords::False) {
@@ -2292,7 +2337,7 @@ impl<'a> Parser<'a> {
                         self.parse_path(LifetimeAndTypesWithColons);
 
                     // `!`, as an operator, is prefix, so we know this isn't that
-                    if self.token == token::Not {
+                    if self.check(&token::Not) {
                         // MACRO INVOCATION expression
                         self.bump();
 
@@ -2309,7 +2354,7 @@ impl<'a> Parser<'a> {
                                                            tts,
                                                            EMPTY_CTXT));
                     }
-                    if self.token == token::OpenDelim(token::Brace) {
+                    if self.check(&token::OpenDelim(token::Brace)) {
                         // This is a struct literal, unless we're prohibited
                         // from parsing struct literals here.
                         if !self.restrictions.contains(RESTRICTION_NO_STRUCT_LITERAL) {
@@ -2840,6 +2885,7 @@ impl<'a> Parser<'a> {
             self.restrictions.contains(RESTRICTION_NO_BAR_OP) {
             return lhs;
         }
+        self.expected_tokens.push(TokenType::Operator);
 
         let cur_opt = self.token.to_binop();
         match cur_opt {
@@ -3079,7 +3125,7 @@ impl<'a> Parser<'a> {
 
     /// Parse the RHS of a local variable declaration (e.g. '= 14;')
     fn parse_initializer(&mut self) -> Option<P<Expr>> {
-        if self.token == token::Eq {
+        if self.check(&token::Eq) {
             self.bump();
             Some(self.parse_expr())
         } else {
@@ -3092,7 +3138,7 @@ impl<'a> Parser<'a> {
         let mut pats = Vec::new();
         loop {
             pats.push(self.parse_pat());
-            if self.token == token::BinOp(token::Or) { self.bump(); }
+            if self.check(&token::BinOp(token::Or)) { self.bump(); }
             else { return pats; }
         };
     }
@@ -3111,14 +3157,19 @@ impl<'a> Parser<'a> {
                 first = false;
             } else {
                 self.expect(&token::Comma);
+
+                if self.token == token::CloseDelim(token::Bracket)
+                        && (before_slice || after.len() != 0) {
+                    break
+                }
             }
 
             if before_slice {
-                if self.token == token::DotDot {
+                if self.check(&token::DotDot) {
                     self.bump();
 
-                    if self.token == token::Comma ||
-                            self.token == token::CloseDelim(token::Bracket) {
+                    if self.check(&token::Comma) ||
+                            self.check(&token::CloseDelim(token::Bracket)) {
                         slice = Some(P(ast::Pat {
                             id: ast::DUMMY_NODE_ID,
                             node: PatWild(PatWildMulti),
@@ -3135,7 +3186,7 @@ impl<'a> Parser<'a> {
             }
 
             let subpat = self.parse_pat();
-            if before_slice && self.token == token::DotDot {
+            if before_slice && self.check(&token::DotDot) {
                 self.bump();
                 slice = Some(subpat);
                 before_slice = false;
@@ -3160,13 +3211,13 @@ impl<'a> Parser<'a> {
             } else {
                 self.expect(&token::Comma);
                 // accept trailing commas
-                if self.token == token::CloseDelim(token::Brace) { break }
+                if self.check(&token::CloseDelim(token::Brace)) { break }
             }
 
             let lo = self.span.lo;
             let hi;
 
-            if self.token == token::DotDot {
+            if self.check(&token::DotDot) {
                 self.bump();
                 if self.token != token::CloseDelim(token::Brace) {
                     let token_str = self.this_token_to_string();
@@ -3187,7 +3238,7 @@ impl<'a> Parser<'a> {
 
             let fieldname = self.parse_ident();
 
-            let (subpat, is_shorthand) = if self.token == token::Colon {
+            let (subpat, is_shorthand) = if self.check(&token::Colon) {
                 match bind_type {
                     BindByRef(..) | BindByValue(MutMutable) => {
                         let token_str = self.this_token_to_string();
@@ -3267,15 +3318,15 @@ impl<'a> Parser<'a> {
           token::OpenDelim(token::Paren) => {
             // parse (pat,pat,pat,...) as tuple
             self.bump();
-            if self.token == token::CloseDelim(token::Paren) {
+            if self.check(&token::CloseDelim(token::Paren)) {
                 self.bump();
                 pat = PatTup(vec![]);
             } else {
                 let mut fields = vec!(self.parse_pat());
                 if self.look_ahead(1, |t| *t != token::CloseDelim(token::Paren)) {
-                    while self.token == token::Comma {
+                    while self.check(&token::Comma) {
                         self.bump();
-                        if self.token == token::CloseDelim(token::Paren) { break; }
+                        if self.check(&token::CloseDelim(token::Paren)) { break; }
                         fields.push(self.parse_pat());
                     }
                 }
@@ -3318,7 +3369,7 @@ impl<'a> Parser<'a> {
             // These expressions are limited to literals (possibly
             // preceded by unary-minus) or identifiers.
             let val = self.parse_literal_maybe_minus();
-            if (self.token == token::DotDotDot) &&
+            if (self.check(&token::DotDotDot)) &&
                     self.look_ahead(1, |t| {
                         *t != token::Comma && *t != token::CloseDelim(token::Bracket)
                     }) {
@@ -3621,7 +3672,7 @@ impl<'a> Parser<'a> {
             let hi = self.span.hi;
 
             if id.name == token::special_idents::invalid.name {
-                if self.token == token::Dot {
+                if self.check(&token::Dot) {
                     let span = self.span;
                     let token_string = self.this_token_to_string();
                     self.span_err(span,
@@ -3934,7 +3985,7 @@ impl<'a> Parser<'a> {
 
         let bounds = self.parse_colon_then_ty_param_bounds();
 
-        let default = if self.token == token::Eq {
+        let default = if self.check(&token::Eq) {
             self.bump();
             Some(self.parse_ty_sum())
         }
@@ -4334,7 +4385,7 @@ impl<'a> Parser<'a> {
                 (optional_unboxed_closure_kind, args)
             }
         };
-        let output = if self.token == token::RArrow {
+        let output = if self.check(&token::RArrow) {
             self.parse_ret_ty()
         } else {
             Return(P(Ty {
@@ -4359,7 +4410,7 @@ impl<'a> Parser<'a> {
                                      seq_sep_trailing_allowed(token::Comma),
                                      |p| p.parse_fn_block_arg());
 
-        let output = if self.token == token::RArrow {
+        let output = if self.check(&token::RArrow) {
             self.parse_ret_ty()
         } else {
             Return(P(Ty {
@@ -4616,7 +4667,7 @@ impl<'a> Parser<'a> {
                                    token::get_ident(class_name)).as_slice());
             }
             self.bump();
-        } else if self.token == token::OpenDelim(token::Paren) {
+        } else if self.check(&token::OpenDelim(token::Paren)) {
             // It's a tuple-like struct.
             is_tuple_like = true;
             fields = self.parse_unspanned_seq(
@@ -4801,7 +4852,7 @@ impl<'a> Parser<'a> {
     fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
         let id_span = self.span;
         let id = self.parse_ident();
-        if self.token == token::Semi {
+        if self.check(&token::Semi) {
             self.bump();
             // This mod is in an external file. Let's go get it!
             let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
@@ -5044,7 +5095,8 @@ impl<'a> Parser<'a> {
         let (maybe_path, ident) = match self.token {
             token::Ident(..) => {
                 let the_ident = self.parse_ident();
-                let path = if self.eat(&token::Eq) {
+                let path = if self.token == token::Eq {
+                    self.bump();
                     let path = self.parse_str();
                     let span = self.span;
                     self.obsolete(span, ObsoleteExternCrateRenaming);
@@ -5184,7 +5236,7 @@ impl<'a> Parser<'a> {
                                 token::get_ident(ident)).as_slice());
                 }
                 kind = StructVariantKind(struct_def);
-            } else if self.token == token::OpenDelim(token::Paren) {
+            } else if self.check(&token::OpenDelim(token::Paren)) {
                 all_nullary = false;
                 let arg_tys = self.parse_enum_variant_seq(
                     &token::OpenDelim(token::Paren),
@@ -5348,7 +5400,7 @@ impl<'a> Parser<'a> {
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
                 return IoviItem(item);
-            } else if self.token == token::OpenDelim(token::Brace) {
+            } else if self.check(&token::OpenDelim(token::Brace)) {
                 return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
             }
 
@@ -5629,7 +5681,7 @@ impl<'a> Parser<'a> {
     fn parse_view_path(&mut self) -> P<ViewPath> {
         let lo = self.span.lo;
 
-        if self.token == token::OpenDelim(token::Brace) {
+        if self.check(&token::OpenDelim(token::Brace)) {
             // use {foo,bar}
             let idents = self.parse_unspanned_seq(
                 &token::OpenDelim(token::Brace),
@@ -5653,7 +5705,7 @@ impl<'a> Parser<'a> {
             self.bump();
             let path_lo = self.span.lo;
             path = vec!(self.parse_ident());
-            while self.token == token::ModSep {
+            while self.check(&token::ModSep) {
                 self.bump();
                 let id = self.parse_ident();
                 path.push(id);
@@ -5677,7 +5729,7 @@ impl<'a> Parser<'a> {
 
           token::ModSep => {
             // foo::bar or foo::{a,b,c} or foo::*
-            while self.token == token::ModSep {
+            while self.check(&token::ModSep) {
                 self.bump();
 
                 match self.token {
@@ -5846,7 +5898,7 @@ impl<'a> Parser<'a> {
         loop {
             match self.parse_foreign_item(attrs, macros_allowed) {
                 IoviNone(returned_attrs) => {
-                    if self.token == token::CloseDelim(token::Brace) {
+                    if self.check(&token::CloseDelim(token::Brace)) {
                         attrs = returned_attrs;
                         break
                     }
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
index d644542db07..3c909a3c708 100644
--- a/src/libterm/terminfo/parm.rs
+++ b/src/libterm/terminfo/parm.rs
@@ -576,7 +576,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> {
 #[cfg(test)]
 mod test {
     use super::{expand,Param,Words,Variables,Number};
-    use std::result::Ok;
+    use std::result::Result::Ok;
 
     #[test]
     fn test_basic_setabf() {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index fbc60c9b342..c943d8706e5 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -51,8 +51,7 @@ use std::collections::TreeMap;
 use stats::Stats;
 use getopts::{OptGroup, optflag, optopt};
 use regex::Regex;
-use serialize::{json, Decodable};
-use serialize::json::{Json, ToJson};
+use serialize::{json, Decodable, Encodable};
 use term::Terminal;
 use term::color::{Color, RED, YELLOW, GREEN, CYAN};
 
@@ -286,6 +285,9 @@ pub struct TestOpts {
     pub logfile: Option<Path>,
     pub nocapture: bool,
     pub color: ColorConfig,
+    pub show_boxplot: bool,
+    pub boxplot_width: uint,
+    pub show_all_stats: bool,
 }
 
 impl TestOpts {
@@ -303,6 +305,9 @@ impl TestOpts {
             logfile: None,
             nocapture: false,
             color: AutoColor,
+            show_boxplot: false,
+            boxplot_width: 50,
+            show_all_stats: false,
         }
     }
 }
@@ -333,7 +338,10 @@ fn optgroups() -> Vec<getopts::OptGroup> {
       getopts::optopt("", "color", "Configure coloring of output:
             auto   = colorize if stdout is a tty and tests are run on serially (default);
             always = always colorize output;
-            never  = never colorize output;", "auto|always|never"))
+            never  = never colorize output;", "auto|always|never"),
+      getopts::optflag("", "boxplot", "Display a boxplot of the benchmark statistics"),
+      getopts::optopt("", "boxplot-width", "Set the boxplot width (default 50)", "WIDTH"),
+      getopts::optflag("", "stats", "Display the benchmark min, max, and quartiles"))
 }
 
 fn usage(binary: &str) {
@@ -424,6 +432,21 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
                                             v))),
     };
 
+    let show_boxplot = matches.opt_present("boxplot");
+    let boxplot_width = match matches.opt_str("boxplot-width") {
+        Some(width) => {
+            match FromStr::from_str(width.as_slice()) {
+                Some(width) => width,
+                None => {
+                    return Some(Err(format!("argument for --boxplot-width must be a uint")));
+                }
+            }
+        }
+        None => 50,
+    };
+
+    let show_all_stats = matches.opt_present("stats");
+
     let test_opts = TestOpts {
         filter: filter,
         run_ignored: run_ignored,
@@ -436,6 +459,9 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         logfile: logfile,
         nocapture: nocapture,
         color: color,
+        show_boxplot: show_boxplot,
+        boxplot_width: boxplot_width,
+        show_all_stats: show_all_stats,
     };
 
     Some(Ok(test_opts))
@@ -486,6 +512,9 @@ struct ConsoleTestState<T> {
     log_out: Option<File>,
     out: OutputLocation<T>,
     use_color: bool,
+    show_boxplot: bool,
+    boxplot_width: uint,
+    show_all_stats: bool,
     total: uint,
     passed: uint,
     failed: uint,
@@ -512,6 +541,9 @@ impl<T: Writer> ConsoleTestState<T> {
             out: out,
             log_out: log_out,
             use_color: use_color(opts),
+            show_boxplot: opts.show_boxplot,
+            boxplot_width: opts.boxplot_width,
+            show_all_stats: opts.show_all_stats,
             total: 0u,
             passed: 0u,
             failed: 0u,
@@ -607,8 +639,31 @@ impl<T: Writer> ConsoleTestState<T> {
             }
             TrBench(ref bs) => {
                 try!(self.write_bench());
-                self.write_plain(format!(": {}",
-                                         fmt_bench_samples(bs)).as_slice())
+
+                if self.show_boxplot {
+                    let mut wr = Vec::new();
+
+                    try!(stats::write_boxplot(&mut wr, &bs.ns_iter_summ, self.boxplot_width));
+
+                    let s = String::from_utf8(wr).unwrap();
+
+                    try!(self.write_plain(format!(": {}", s).as_slice()));
+                }
+
+                if self.show_all_stats {
+                    let mut wr = Vec::new();
+
+                    try!(stats::write_5_number_summary(&mut wr, &bs.ns_iter_summ));
+
+                    let s = String::from_utf8(wr).unwrap();
+
+                    try!(self.write_plain(format!(": {}", s).as_slice()));
+                } else {
+                    try!(self.write_plain(format!(": {}",
+                                                  fmt_bench_samples(bs)).as_slice()));
+                }
+
+                Ok(())
             }
         });
         self.write_plain("\n")
@@ -681,14 +736,14 @@ impl<T: Writer> ConsoleTestState<T> {
                 }
                 Improvement(pct) => {
                     improved += 1;
-                    try!(self.write_plain(format!(": {}", *k).as_slice()));
+                    try!(self.write_plain(format!(": {} ", *k).as_slice()));
                     try!(self.write_improved());
                     try!(self.write_plain(format!(" by {:.2}%\n",
                                                   pct as f64).as_slice()));
                 }
                 Regression(pct) => {
                     regressed += 1;
-                    try!(self.write_plain(format!(": {}", *k).as_slice()));
+                    try!(self.write_plain(format!(": {} ", *k).as_slice()));
                     try!(self.write_regressed());
                     try!(self.write_plain(format!(" by {:.2}%\n",
                                                   pct as f64).as_slice()));
@@ -860,6 +915,9 @@ fn should_sort_failures_before_printing_them() {
         log_out: None,
         out: Raw(Vec::new()),
         use_color: false,
+        show_boxplot: false,
+        boxplot_width: 0,
+        show_all_stats: false,
         total: 0u,
         passed: 0u,
         failed: 0u,
@@ -1100,17 +1158,6 @@ fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult {
     }
 }
 
-
-impl ToJson for Metric {
-    fn to_json(&self) -> json::Json {
-        let mut map = TreeMap::new();
-        map.insert("value".to_string(), json::Json::F64(self.value));
-        map.insert("noise".to_string(), json::Json::F64(self.noise));
-        json::Json::Object(map)
-    }
-}
-
-
 impl MetricMap {
 
     pub fn new() -> MetricMap {
@@ -1138,14 +1185,8 @@ impl MetricMap {
     pub fn save(&self, p: &Path) -> io::IoResult<()> {
         let mut file = try!(File::create(p));
         let MetricMap(ref map) = *self;
-
-        // FIXME(pcwalton): Yuck.
-        let mut new_map = TreeMap::new();
-        for (ref key, ref value) in map.iter() {
-            new_map.insert(key.to_string(), (*value).clone());
-        }
-
-        new_map.to_json().to_pretty_writer(&mut file)
+        let mut enc = json::PrettyEncoder::new(&mut file);
+        map.encode(&mut enc)
     }
 
     /// Compare against another MetricMap. Optionally compare all
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index ab6756ffce3..c157fb10bd4 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -331,8 +331,8 @@ pub fn winsorize<T: Float + FromPrimitive>(samples: &mut [T], pct: T) {
 }
 
 /// Render writes the min, max and quartiles of the provided `Summary` to the provided `Writer`.
-pub fn write_5_number_summary<T: Float + Show>(w: &mut io::Writer,
-                                               s: &Summary<T>) -> io::IoResult<()> {
+pub fn write_5_number_summary<W: Writer, T: Float + Show>(w: &mut W,
+                                                          s: &Summary<T>) -> io::IoResult<()> {
     let (q1,q2,q3) = s.quartiles;
     write!(w, "(min={}, q1={}, med={}, q3={}, max={})",
                      s.min,
@@ -353,8 +353,8 @@ pub fn write_5_number_summary<T: Float + Show>(w: &mut io::Writer,
 /// ```{.ignore}
 ///   10 |        [--****#******----------]          | 40
 /// ```
-pub fn write_boxplot<T: Float + Show + FromPrimitive>(
-                     w: &mut io::Writer,
+pub fn write_boxplot<W: Writer, T: Float + Show + FromPrimitive>(
+                     w: &mut W,
                      s: &Summary<T>,
                      width_hint: uint)
                       -> io::IoResult<()> {
@@ -473,7 +473,7 @@ mod tests {
         let summ2 = Summary::new(samples);
 
         let mut w = io::stdout();
-        let w = &mut w as &mut io::Writer;
+        let w = &mut w;
         (write!(w, "\n")).unwrap();
         write_5_number_summary(w, &summ2).unwrap();
         (write!(w, "\n")).unwrap();
@@ -1028,7 +1028,7 @@ mod tests {
     fn test_boxplot_nonpositive() {
         fn t(s: &Summary<f64>, expected: String) {
             let mut m = Vec::new();
-            write_boxplot(&mut m as &mut io::Writer, s, 30).unwrap();
+            write_boxplot(&mut m, s, 30).unwrap();
             let out = String::from_utf8(m).unwrap();
             assert_eq!(out, expected);
         }
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index a77a6276a8b..06a0df852b9 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -1262,7 +1262,7 @@ mod tests {
                 InvalidFormatSpecifier};
 
     use std::f64;
-    use std::result::{Err, Ok};
+    use std::result::Result::{Err, Ok};
     use std::time::Duration;
     use self::test::Bencher;
 
diff --git a/src/libunicode/normalize.rs b/src/libunicode/normalize.rs
index cd46fc6a56d..29a8b1204b8 100644
--- a/src/libunicode/normalize.rs
+++ b/src/libunicode/normalize.rs
@@ -10,8 +10,9 @@
 
 //! Functions for computing canonical and compatible decompositions for Unicode characters.
 
-use core::cmp::{Equal, Less, Greater};
-use core::option::{Option, Some, None};
+use core::cmp::Ordering::{Equal, Less, Greater};
+use core::option::Option;
+use core::option::Option::{Some, None};
 use core::slice;
 use core::slice::SlicePrelude;
 use tables::normalization::{canonical_table, compatibility_table, composition_table};
diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs
index 7cece6701dc..c91ce5c6464 100644
--- a/src/libunicode/tables.rs
+++ b/src/libunicode/tables.rs
@@ -17,7 +17,7 @@
 pub const UNICODE_VERSION: (uint, uint, uint) = (7, 0, 0);
 
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
-    use core::cmp::{Equal, Less, Greater};
+    use core::cmp::Ordering::{Equal, Less, Greater};
     use core::slice::SlicePrelude;
     r.binary_search(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
@@ -6241,7 +6241,7 @@ pub mod normalization {
 
 
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
-        use core::cmp::{Equal, Less, Greater};
+        use core::cmp::Ordering::{Equal, Less, Greater};
         use core::slice::SlicePrelude;
         use core::slice;
         match r.binary_search(|&(lo, hi, _)| {
@@ -6366,10 +6366,11 @@ pub mod normalization {
 }
 
 pub mod conversions {
-    use core::cmp::{Equal, Less, Greater};
+    use core::cmp::Ordering::{Equal, Less, Greater};
     use core::slice::SlicePrelude;
     use core::tuple::Tuple2;
-    use core::option::{Option, Some, None};
+    use core::option::Option;
+    use core::option::Option::{Some, None};
     use core::slice;
 
     pub fn to_lower(c: char) -> char {
@@ -6934,12 +6935,13 @@ pub mod conversions {
 }
 
 pub mod charwidth {
-    use core::option::{Option, Some, None};
+    use core::option::Option;
+    use core::option::Option::{Some, None};
     use core::slice::SlicePrelude;
     use core::slice;
 
     fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
-        use core::cmp::{Equal, Less, Greater};
+        use core::cmp::Ordering::{Equal, Less, Greater};
         match r.binary_search(|&(lo, hi, _, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
@@ -7154,7 +7156,7 @@ pub mod grapheme {
     }
 
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
-        use core::cmp::{Equal, Less, Greater};
+        use core::cmp::Ordering::{Equal, Less, Greater};
         match r.binary_search(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs
index a5f76142575..e4b2b682b2c 100644
--- a/src/libunicode/u_str.rs
+++ b/src/libunicode/u_str.rs
@@ -21,7 +21,8 @@ use core::slice::SlicePrelude;
 use core::iter::{Filter, AdditiveIterator, Iterator, IteratorExt};
 use core::iter::{DoubleEndedIterator, DoubleEndedIteratorExt};
 use core::kinds::Sized;
-use core::option::{Option, None, Some};
+use core::option::Option;
+use core::option::Option::{None, Some};
 use core::str::{CharSplits, StrPrelude};
 use u_char::UnicodeChar;
 use tables::grapheme::GraphemeCat;
diff --git a/src/snapshots.txt b/src/snapshots.txt
index 0faf6840f06..a1a840b4deb 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,3 +1,12 @@
+S 2014-12-05 361baab
+  freebsd-x86_64 73cbae4168538a07facd81cca45ed672badb7c3a
+  linux-i386 211cf0fbdbc7045b765e7b92d92049bbe6788513
+  linux-x86_64 f001cec306fc1ac77504884acf5dac2e7b39e164
+  macos-i386 751dc02fac96114361c56eb45ce52e7a58d555e0
+  macos-x86_64 58cad0275d7b33412501d7dd3386b924d2304e83
+  winnt-i386 872c56b88cebd7d590fd00bcbd264f0003b4427b
+  winnt-x86_64 2187d8b3187c03f95cd4e56a582f55ec0cfa8df9
+
 S 2014-11-21 c9f6d69
   freebsd-x86_64 0ef316e7c369177de043e69e964418bd637cbfc0
   linux-i386 c8342e762a1720be939ed7c6a39bdaa27892f66f
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs
index d06e6c8cd19..863c3c879a7 100644
--- a/src/test/bench/msgsend-ring-mutex-arcs.rs
+++ b/src/test/bench/msgsend-ring-mutex-arcs.rs
@@ -19,28 +19,30 @@
 // ignore-lexer-test FIXME #15679
 
 use std::os;
-use std::sync::{Arc, Future, Mutex};
+use std::sync::{Arc, Future, Mutex, Condvar};
 use std::time::Duration;
 use std::uint;
 
 // A poor man's pipe.
-type pipe = Arc<Mutex<Vec<uint>>>;
+type pipe = Arc<(Mutex<Vec<uint>>, Condvar)>;
 
 fn send(p: &pipe, msg: uint) {
-    let mut arr = p.lock();
+    let &(ref lock, ref cond) = &**p;
+    let mut arr = lock.lock();
     arr.push(msg);
-    arr.cond.signal();
+    cond.notify_one();
 }
 fn recv(p: &pipe) -> uint {
-    let mut arr = p.lock();
+    let &(ref lock, ref cond) = &**p;
+    let mut arr = lock.lock();
     while arr.is_empty() {
-        arr.cond.wait();
+        cond.wait(&arr);
     }
     arr.pop().unwrap()
 }
 
 fn init() -> (pipe,pipe) {
-    let m = Arc::new(Mutex::new(Vec::new()));
+    let m = Arc::new((Mutex::new(Vec::new()), Condvar::new()));
     ((&m).clone(), m)
 }
 
diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs
deleted file mode 100644
index 03066d40512..00000000000
--- a/src/test/bench/msgsend-ring-rw-arcs.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This test creates a bunch of tasks that simultaneously send to each
-// other in a ring. The messages should all be basically
-// independent.
-// This is like msgsend-ring-pipes but adapted to use Arcs.
-
-// This also serves as a pipes test, because Arcs are implemented with pipes.
-
-// no-pretty-expanded FIXME #15189
-// ignore-lexer-test FIXME #15679
-
-use std::os;
-use std::sync::{RWLock, Arc, Future};
-use std::time::Duration;
-use std::uint;
-
-// A poor man's pipe.
-type pipe = Arc<RWLock<Vec<uint>>>;
-
-fn send(p: &pipe, msg: uint) {
-    let mut arr = p.write();
-    arr.push(msg);
-    arr.cond.signal();
-}
-fn recv(p: &pipe) -> uint {
-    let mut arr = p.write();
-    while arr.is_empty() {
-        arr.cond.wait();
-    }
-    arr.pop().unwrap()
-}
-
-fn init() -> (pipe,pipe) {
-    let x = Arc::new(RWLock::new(Vec::new()));
-    ((&x).clone(), x)
-}
-
-
-fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
-    let mut num_chan = Some(num_chan);
-    let mut num_port = Some(num_port);
-    // Send/Receive lots of messages.
-    for j in range(0u, count) {
-        //println!("task %?, iter %?", i, j);
-        let num_chan2 = num_chan.take().unwrap();
-        let num_port2 = num_port.take().unwrap();
-        send(&num_chan2, i * j);
-        num_chan = Some(num_chan2);
-        let _n = recv(&num_port2);
-        //log(error, _n);
-        num_port = Some(num_port2);
-    };
-}
-
-fn main() {
-    let args = os::args();
-    let args = if os::getenv("RUST_BENCH").is_some() {
-        vec!("".to_string(), "100".to_string(), "10000".to_string())
-    } else if args.len() <= 1u {
-        vec!("".to_string(), "10".to_string(), "100".to_string())
-    } else {
-        args.clone().into_iter().collect()
-    };
-
-    let num_tasks = from_str::<uint>(args[1].as_slice()).unwrap();
-    let msg_per_task = from_str::<uint>(args[2].as_slice()).unwrap();
-
-    let (mut num_chan, num_port) = init();
-
-    let mut p = Some((num_chan, num_port));
-    let dur = Duration::span(|| {
-        let (mut num_chan, num_port) = p.take().unwrap();
-
-        // create the ring
-        let mut futures = Vec::new();
-
-        for i in range(1u, num_tasks) {
-            //println!("spawning %?", i);
-            let (new_chan, num_port) = init();
-            let num_chan_2 = num_chan.clone();
-            let new_future = Future::spawn(proc() {
-                thread_ring(i, msg_per_task, num_chan_2, num_port)
-            });
-            futures.push(new_future);
-            num_chan = new_chan;
-        };
-
-        // do our iteration
-        thread_ring(0, msg_per_task, num_chan, num_port);
-
-        // synchronize
-        for f in futures.iter_mut() {
-            let _ = f.get();
-        }
-    });
-
-    // all done, report stats.
-    let num_msgs = num_tasks * msg_per_task;
-    let rate = (num_msgs as f64) / (dur.num_milliseconds() as f64);
-
-    println!("Sent {} messages in {} ms", num_msgs, dur.num_milliseconds());
-    println!("  {} messages / second", rate / 1000.0);
-    println!("  {} μs / message", 1000000. / rate / 1000.0);
-}
diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs
index 4005c11e6b6..45d2cbea8fa 100644
--- a/src/test/bench/shootout-k-nucleotide-pipes.rs
+++ b/src/test/bench/shootout-k-nucleotide-pipes.rs
@@ -77,8 +77,8 @@ fn sort_and_fmt(mm: &HashMap<Vec<u8> , uint>, total: uint) -> String {
 fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
    let key = key.into_ascii().as_slice().to_lowercase().into_string();
    match mm.get(key.as_bytes()) {
-      option::None      => { return 0u; }
-      option::Some(&num) => { return num; }
+      option::Option::None      => { return 0u; }
+      option::Option::Some(&num) => { return num; }
    }
 }
 
@@ -190,8 +190,8 @@ fn main() {
            // start processing if this is the one
            ('>', false) => {
                match line.as_slice().slice_from(1).find_str("THREE") {
-                   option::Some(_) => { proc_mode = true; }
-                   option::None    => { }
+                   option::Option::Some(_) => { proc_mode = true; }
+                   option::Option::None    => { }
                }
            }
 
diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs
index b030e7bb93e..8ed041513c4 100644
--- a/src/test/bench/shootout-k-nucleotide.rs
+++ b/src/test/bench/shootout-k-nucleotide.rs
@@ -295,7 +295,7 @@ fn main() {
         let fd = std::io::File::open(&Path::new("shootout-k-nucleotide.data"));
         get_sequence(&mut std::io::BufferedReader::new(fd), ">THREE")
     } else {
-        get_sequence(&mut std::io::stdin(), ">THREE")
+        get_sequence(&mut *std::io::stdin().lock(), ">THREE")
     };
     let input = Arc::new(input);
 
diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs
index 9cc86e91fbe..15a5cb0c9bf 100644
--- a/src/test/bench/shootout-pfib.rs
+++ b/src/test/bench/shootout-pfib.rs
@@ -21,7 +21,7 @@
 extern crate getopts;
 
 use std::os;
-use std::result::{Ok, Err};
+use std::result::Result::{Ok, Err};
 use std::task;
 use std::time::Duration;
 
diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs
index 6664eeecd5d..c55f85f40e8 100644
--- a/src/test/bench/sudoku.rs
+++ b/src/test/bench/sudoku.rs
@@ -65,7 +65,7 @@ impl Sudoku {
         return true;
     }
 
-    pub fn read(mut reader: BufferedReader<StdReader>) -> Sudoku {
+    pub fn read(mut reader: &mut BufferedReader<StdReader>) -> Sudoku {
         /* assert first line is exactly "9,9" */
         assert!(reader.read_line().unwrap() == "9,9".to_string());
 
@@ -284,7 +284,7 @@ fn main() {
     let mut sudoku = if use_default {
         Sudoku::from_vec(&DEFAULT_SUDOKU)
     } else {
-        Sudoku::read(io::stdin())
+        Sudoku::read(&mut *io::stdin().lock())
     };
     sudoku.solve();
     sudoku.write(&mut io::stdout());
diff --git a/src/test/compile-fail/rustc-diagnostics-2.rs b/src/test/compile-fail/better-expected.rs
index c4e011bcea0..489f892726a 100644
--- a/src/test/compile-fail/rustc-diagnostics-2.rs
+++ b/src/test/compile-fail/better-expected.rs
@@ -8,13 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(rustc_diagnostic_macros)]
-
-__register_diagnostic!(E0001)
-__register_diagnostic!(E0001)
-//~^ ERROR diagnostic code E0001 already registered
-
 fn main() {
+    let x: [int ..3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `..`
 }
-
-__build_diagnostic_array!(DIAGNOSTICS)
diff --git a/src/test/compile-fail/borrow-tuple-fields.rs b/src/test/compile-fail/borrow-tuple-fields.rs
index 519bad4e627..1d09143c24d 100644
--- a/src/test/compile-fail/borrow-tuple-fields.rs
+++ b/src/test/compile-fail/borrow-tuple-fields.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tuple_indexing)]
-
 struct Foo(Box<int>, int);
 
 struct Bar(int, int);
diff --git a/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs b/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs
index fcb09c20000..daad1afedaa 100644
--- a/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs
+++ b/src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs
@@ -14,6 +14,6 @@ fn main() {
     //~^ ERROR: cannot assign to immutable captured outer variable in a proc `x`
 
     let s = std::io::stdin();
-    proc() { s.lines(); };
+    proc() { s.read_to_end(); };
     //~^ ERROR: cannot borrow immutable captured outer variable in a proc `s` as mutable
 }
diff --git a/src/test/compile-fail/column-offset-1-based.rs b/src/test/compile-fail/column-offset-1-based.rs
index a00ded61758..621b480fe77 100644
--- a/src/test/compile-fail/column-offset-1-based.rs
+++ b/src/test/compile-fail/column-offset-1-based.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-# //~ ERROR 11:1: 11:2 error: expected `[`, found `<eof>`
+# //~ ERROR 11:1: 11:2 error: expected one of `!` or `[`, found `<eof>`
diff --git a/src/test/compile-fail/empty-impl-semicolon.rs b/src/test/compile-fail/empty-impl-semicolon.rs
index b5f17eef886..a598252f1b6 100644
--- a/src/test/compile-fail/empty-impl-semicolon.rs
+++ b/src/test/compile-fail/empty-impl-semicolon.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-impl Foo; //~ ERROR expected `{`, found `;`
+impl Foo; //~ ERROR expected one of `(`, `+`, `::`, or `{`, found `;`
diff --git a/src/test/compile-fail/if-let.rs b/src/test/compile-fail/if-let.rs
index b82fb7a94c9..88b6854bb1d 100644
--- a/src/test/compile-fail/if-let.rs
+++ b/src/test/compile-fail/if-let.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules,if_let)]
+#![feature(macro_rules)]
 
 fn macros() {
     macro_rules! foo{
diff --git a/src/test/compile-fail/issue-1655.rs b/src/test/compile-fail/issue-1655.rs
index 6bdcf5c5edc..a8704f7545f 100644
--- a/src/test/compile-fail/issue-1655.rs
+++ b/src/test/compile-fail/issue-1655.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:expected `[`, found `vec`
+// error-pattern:expected one of `!` or `[`, found `vec`
 mod blade_runner {
     #vec[doc(
         brief = "Blade Runner is probably the best movie ever",
diff --git a/src/test/compile-fail/issue-18566.rs b/src/test/compile-fail/issue-18566.rs
index 89b1d8540d8..f64d8fee2d8 100644
--- a/src/test/compile-fail/issue-18566.rs
+++ b/src/test/compile-fail/issue-18566.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tuple_indexing)]
-
 struct MyPtr<'a>(&'a mut uint);
 impl<'a> Deref<uint> for MyPtr<'a> {
     fn deref<'b>(&'b self) -> &'b uint { self.0 }
diff --git a/src/test/compile-fail/rustc-diagnostics-1.rs b/src/test/compile-fail/issue-18959.rs
index 55d836092fa..3d126790335 100644
--- a/src/test/compile-fail/rustc-diagnostics-1.rs
+++ b/src/test/compile-fail/issue-18959.rs
@@ -8,21 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(rustc_diagnostic_macros)]
+pub trait Foo for Sized? { fn foo<T>(&self, ext_thing: &T); }
+pub trait Bar for Sized?: Foo { }
+impl<T: Foo> Bar for T { }
 
-__register_diagnostic!(E0001)
-__register_diagnostic!(E0003)
-
-fn main() {
-    __diagnostic_used!(E0002);
-    //~^ ERROR unknown diagnostic code E0002
+pub struct Thing;
+impl Foo for Thing {
+    fn foo<T>(&self, _: &T) {}
+}
 
-    __diagnostic_used!(E0001);
-    //~^ NOTE previous invocation
+#[inline(never)] fn foo(b: &Bar) { b.foo(&0u) }
 
-    __diagnostic_used!(E0001);
-    //~^ WARNING diagnostic code E0001 already used
+fn main() {
+    let mut thing = Thing;
+    let test: &Bar = &mut thing; //~ ERROR cannot convert to a trait object because trait `Foo`
+    foo(test);
 }
-
-__build_diagnostic_array!(DIAGNOSTICS)
-//~^ WARN diagnostic code E0003 never used
diff --git a/src/test/compile-fail/issue-19096.rs b/src/test/compile-fail/issue-19096.rs
index 7f42abb3acc..6b67814aab3 100644
--- a/src/test/compile-fail/issue-19096.rs
+++ b/src/test/compile-fail/issue-19096.rs
@@ -12,5 +12,5 @@
 
 fn main() {
     let t = (42i, 42i);
-    t.0::<int>; //~ ERROR expected one of `;`, `}`, found `::`
+    t.0::<int>; //~ ERROR expected one of `.`, `;`, `}`, or an operator, found `::`
 }
diff --git a/src/test/compile-fail/issue-19244-1.rs b/src/test/compile-fail/issue-19244-1.rs
index 4fcbb878890..7ca83f21305 100644
--- a/src/test/compile-fail/issue-19244-1.rs
+++ b/src/test/compile-fail/issue-19244-1.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tuple_indexing)]
-
 const TUP: (uint,) = (42,);
 
 fn main() {
diff --git a/src/test/compile-fail/issue-19498.rs b/src/test/compile-fail/issue-19498.rs
new file mode 100644
index 00000000000..02b9c42b65b
--- /dev/null
+++ b/src/test/compile-fail/issue-19498.rs
@@ -0,0 +1,21 @@
+// 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 self::A; //~ ERROR import `A` conflicts with existing submodule
+use self::B; //~ ERROR import `B` conflicts with existing submodule
+mod A {}
+pub mod B {}
+
+mod C {
+    use C::D; //~ ERROR import `D` conflicts with existing submodule
+    mod D {}
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-3036.rs b/src/test/compile-fail/issue-3036.rs
index 5f56f6b8b6b..16834f49165 100644
--- a/src/test/compile-fail/issue-3036.rs
+++ b/src/test/compile-fail/issue-3036.rs
@@ -13,4 +13,4 @@
 fn main()
 {
     let x = 3
-} //~ ERROR: expected `;`, found `}`
+} //~ ERROR: expected one of `.`, `;`, or an operator, found `}`
diff --git a/src/test/compile-fail/issue-5806.rs b/src/test/compile-fail/issue-5806.rs
index 702f02c721d..597366a1b35 100644
--- a/src/test/compile-fail/issue-5806.rs
+++ b/src/test/compile-fail/issue-5806.rs
@@ -18,9 +18,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-freebsd FIXME #12460
-
 #[path = "../compile-fail"]
-mod foo; //~ ERROR: illegal operation on a directory
+mod foo; //~ ERROR: a directory
 
 fn main() {}
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 365081aee1a..8d4ecde692d 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -17,6 +17,9 @@
 //! Some garbage docs for the crate here
 #![doc="More garbage"]
 
+type Typedef = String;
+pub type PubTypedef = String; //~ ERROR: missing documentation
+
 struct Foo {
     a: int,
     b: int,
diff --git a/src/test/compile-fail/lint-unnecessary-parens.rs b/src/test/compile-fail/lint-unnecessary-parens.rs
index 826a4ea5a80..b71effa6f86 100644
--- a/src/test/compile-fail/lint-unnecessary-parens.rs
+++ b/src/test/compile-fail/lint-unnecessary-parens.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![deny(unused_parens)]
-#![feature(if_let,while_let)]
 
 #[deriving(Eq, PartialEq)]
 struct X { y: bool }
diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs
index d9bf722f73e..b1a6c82a734 100644
--- a/src/test/compile-fail/lint-unused-imports.rs
+++ b/src/test/compile-fail/lint-unused-imports.rs
@@ -18,8 +18,8 @@ use std::mem::*;            // shouldn't get errors for not using
                             // everything imported
 
 // Should get errors for both 'Some' and 'None'
-use std::option::{Some, None}; //~ ERROR unused import
-                                //~^ ERROR unused import
+use std::option::Option::{Some, None}; //~ ERROR unused import
+                                     //~^ ERROR unused import
 
 use test::A;       //~ ERROR unused import
 // Be sure that if we just bring some methods into scope that they're also
diff --git a/src/test/compile-fail/match-vec-invalid.rs b/src/test/compile-fail/match-vec-invalid.rs
index 51e83c14aa0..3e073d34f32 100644
--- a/src/test/compile-fail/match-vec-invalid.rs
+++ b/src/test/compile-fail/match-vec-invalid.rs
@@ -11,7 +11,7 @@
 fn main() {
     let a = Vec::new();
     match a {
-        [1, tail.., tail..] => {}, //~ ERROR: expected `,`, found `..`
+        [1, tail.., tail..] => {}, //~ ERROR: expected one of `!`, `,`, or `@`, found `..`
         _ => ()
     }
 }
diff --git a/src/test/compile-fail/move-fragments-1.rs b/src/test/compile-fail/move-fragments-1.rs
index ccf12cf79e1..e45862a7fc6 100644
--- a/src/test/compile-fail/move-fragments-1.rs
+++ b/src/test/compile-fail/move-fragments-1.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tuple_indexing)]
-
 // Test that we correctly compute the move fragments for a fn.
 //
 // Note that the code below is not actually incorrect; the
diff --git a/src/test/compile-fail/move-out-of-tuple-field.rs b/src/test/compile-fail/move-out-of-tuple-field.rs
index 7f55a78e8b7..7fcb54e0467 100644
--- a/src/test/compile-fail/move-out-of-tuple-field.rs
+++ b/src/test/compile-fail/move-out-of-tuple-field.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tuple_indexing)]
-
 struct Foo(Box<int>);
 
 fn main() {
diff --git a/src/test/compile-fail/multitrait.rs b/src/test/compile-fail/multitrait.rs
index 795e3807d5e..7add747fbfa 100644
--- a/src/test/compile-fail/multitrait.rs
+++ b/src/test/compile-fail/multitrait.rs
@@ -12,7 +12,7 @@ struct S {
  y: int
 }
 
-impl Cmp, ToString for S { //~ ERROR: expected `{`, found `,`
+impl Cmp, ToString for S { //~ ERROR: expected one of `(`, `+`, `::`, or `{`, found `,`
   fn eq(&&other: S) { false }
   fn to_string(&self) -> String { "hi".to_string() }
 }
diff --git a/src/test/compile-fail/mut-patterns.rs b/src/test/compile-fail/mut-patterns.rs
index a33a603f7f5..a78e82bb73c 100644
--- a/src/test/compile-fail/mut-patterns.rs
+++ b/src/test/compile-fail/mut-patterns.rs
@@ -12,5 +12,5 @@
 
 pub fn main() {
     struct Foo { x: int }
-    let mut Foo { x: x } = Foo { x: 3 }; //~ ERROR: expected `;`, found `{`
+    let mut Foo { x: x } = Foo { x: 3 }; //~ ERROR: expected one of `:`, `;`, `=`, or `@`, found `{`
 }
diff --git a/src/test/compile-fail/rustc-diagnostics-3.rs b/src/test/compile-fail/new-unicode-escapes-1.rs
index d160664a48c..f2422830a21 100644
--- a/src/test/compile-fail/rustc-diagnostics-3.rs
+++ b/src/test/compile-fail/new-unicode-escapes-1.rs
@@ -8,13 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-__register_diagnostic!(E0001)
-//~^ ERROR macro undefined: '__register_diagnostic!'
-
-fn main() {
-    __diagnostic_used!(E0001);
-    //~^ ERROR macro undefined: '__diagnostic_used!'
+pub fn main() {
+    let s = "\u{2603"; //~ ERROR unterminated unicode escape (needed a `}`)
 }
-
-__build_diagnostic_array!(DIAGNOSTICS)
-//~^ ERROR macro undefined: '__build_diagnostic_array!'
diff --git a/src/test/compile-fail/new-unicode-escapes-2.rs b/src/test/compile-fail/new-unicode-escapes-2.rs
new file mode 100644
index 00000000000..5da8674c37e
--- /dev/null
+++ b/src/test/compile-fail/new-unicode-escapes-2.rs
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    let s = "\u{260311111111}"; //~ ERROR overlong unicode escape (can have at most 6 hex digits)
+}
diff --git a/src/test/compile-fail/new-unicode-escapes-3.rs b/src/test/compile-fail/new-unicode-escapes-3.rs
new file mode 100644
index 00000000000..7c64d02efd7
--- /dev/null
+++ b/src/test/compile-fail/new-unicode-escapes-3.rs
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    let s = "\u{d805}"; //~ ERROR illegal unicode character escape
+}
diff --git a/src/test/compile-fail/new-unicode-escapes-4.rs b/src/test/compile-fail/new-unicode-escapes-4.rs
new file mode 100644
index 00000000000..ffc2b11e0c1
--- /dev/null
+++ b/src/test/compile-fail/new-unicode-escapes-4.rs
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    let s = "\u{lol}"; //~ ERROR illegal character in unicode escape
+}
diff --git a/src/test/compile-fail/omitted-arg-in-item-fn.rs b/src/test/compile-fail/omitted-arg-in-item-fn.rs
index c5ff885997b..729b45df8b4 100644
--- a/src/test/compile-fail/omitted-arg-in-item-fn.rs
+++ b/src/test/compile-fail/omitted-arg-in-item-fn.rs
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo(x) { //~ ERROR expected `:`, found `)`
+fn foo(x) { //~ ERROR expected one of `!`, `:`, or `@`, found `)`
 }
diff --git a/src/test/compile-fail/pat-range-bad-dots.rs b/src/test/compile-fail/pat-range-bad-dots.rs
index 5605caaeeed..7fe073a4c3d 100644
--- a/src/test/compile-fail/pat-range-bad-dots.rs
+++ b/src/test/compile-fail/pat-range-bad-dots.rs
@@ -10,7 +10,7 @@
 
 pub fn main() {
     match 22i {
-        0 .. 3 => {} //~ ERROR expected `=>`, found `..`
+        0 .. 3 => {} //~ ERROR expected one of `...`, `=>`, or `|`, found `..`
         _ => {}
     }
 }
diff --git a/src/test/compile-fail/raw-str-unbalanced.rs b/src/test/compile-fail/raw-str-unbalanced.rs
index 4f3fb7d5b8a..3403b28fdc9 100644
--- a/src/test/compile-fail/raw-str-unbalanced.rs
+++ b/src/test/compile-fail/raw-str-unbalanced.rs
@@ -10,5 +10,5 @@
 
 static s: &'static str =
     r#"
-      "## //~ ERROR expected `;`, found `#`
+      "## //~ ERROR expected one of `.`, `;`, or an operator, found `#`
 ;
diff --git a/src/test/compile-fail/removed-syntax-closure-lifetime.rs b/src/test/compile-fail/removed-syntax-closure-lifetime.rs
index a726e30b1de..a07832d5bb7 100644
--- a/src/test/compile-fail/removed-syntax-closure-lifetime.rs
+++ b/src/test/compile-fail/removed-syntax-closure-lifetime.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type closure = Box<lt/fn()>; //~ ERROR expected `,`, found `/`
+type closure = Box<lt/fn()>; //~ ERROR expected one of `(`, `+`, `,`, `::`, or `>`, found `/`
diff --git a/src/test/compile-fail/removed-syntax-enum-newtype.rs b/src/test/compile-fail/removed-syntax-enum-newtype.rs
index b9c9c5f0a53..ba1b5a616df 100644
--- a/src/test/compile-fail/removed-syntax-enum-newtype.rs
+++ b/src/test/compile-fail/removed-syntax-enum-newtype.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum e = int; //~ ERROR expected `{`, found `=`
+enum e = int; //~ ERROR expected one of `<` or `{`, found `=`
diff --git a/src/test/compile-fail/removed-syntax-fixed-vec.rs b/src/test/compile-fail/removed-syntax-fixed-vec.rs
index 917b4e03ad0..fe49d1f4a8d 100644
--- a/src/test/compile-fail/removed-syntax-fixed-vec.rs
+++ b/src/test/compile-fail/removed-syntax-fixed-vec.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type v = [int * 3]; //~ ERROR expected `]`, found `*`
+type v = [int * 3]; //~ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `*`
diff --git a/src/test/compile-fail/removed-syntax-larrow-init.rs b/src/test/compile-fail/removed-syntax-larrow-init.rs
index b2e856750df..1474cc9dd39 100644
--- a/src/test/compile-fail/removed-syntax-larrow-init.rs
+++ b/src/test/compile-fail/removed-syntax-larrow-init.rs
@@ -11,5 +11,5 @@
 fn removed_moves() {
     let mut x = 0;
     let y <- x;
-    //~^ ERROR expected `;`, found `<-`
+    //~^ ERROR expected one of `!`, `:`, `;`, `=`, or `@`, found `<-`
 }
diff --git a/src/test/compile-fail/removed-syntax-larrow-move.rs b/src/test/compile-fail/removed-syntax-larrow-move.rs
index e39fbe0f950..552c9f2efa2 100644
--- a/src/test/compile-fail/removed-syntax-larrow-move.rs
+++ b/src/test/compile-fail/removed-syntax-larrow-move.rs
@@ -12,5 +12,5 @@ fn removed_moves() {
     let mut x = 0;
     let y = 0;
     y <- x;
-    //~^ ERROR expected one of `;`, `}`, found `<-`
+    //~^ ERROR expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `<-`
 }
diff --git a/src/test/compile-fail/removed-syntax-mut-vec-expr.rs b/src/test/compile-fail/removed-syntax-mut-vec-expr.rs
index b20da6346f7..437f871f8ea 100644
--- a/src/test/compile-fail/removed-syntax-mut-vec-expr.rs
+++ b/src/test/compile-fail/removed-syntax-mut-vec-expr.rs
@@ -11,5 +11,5 @@
 fn f() {
     let v = [mut 1, 2, 3, 4];
     //~^  ERROR expected identifier, found keyword `mut`
-    //~^^ ERROR expected `]`, found `1`
+    //~^^ ERROR expected one of `!`, `,`, `.`, `::`, `]`, `{`, or an operator, found `1`
 }
diff --git a/src/test/compile-fail/removed-syntax-mut-vec-ty.rs b/src/test/compile-fail/removed-syntax-mut-vec-ty.rs
index c5eec2ef6e1..af469fadf98 100644
--- a/src/test/compile-fail/removed-syntax-mut-vec-ty.rs
+++ b/src/test/compile-fail/removed-syntax-mut-vec-ty.rs
@@ -10,4 +10,4 @@
 
 type v = [mut int];
     //~^  ERROR expected identifier, found keyword `mut`
-    //~^^ ERROR expected `]`, found `int`
+    //~^^ ERROR expected one of `(`, `+`, `,`, `::`, or `]`, found `int`
diff --git a/src/test/compile-fail/removed-syntax-ptr-lifetime.rs b/src/test/compile-fail/removed-syntax-ptr-lifetime.rs
index 0468ddd389a..1a1c4c9b40a 100644
--- a/src/test/compile-fail/removed-syntax-ptr-lifetime.rs
+++ b/src/test/compile-fail/removed-syntax-ptr-lifetime.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type bptr = &lifetime/int; //~ ERROR expected `;`, found `/`
+type bptr = &lifetime/int; //~ ERROR expected one of `(`, `+`, `::`, or `;`, found `/`
diff --git a/src/test/compile-fail/removed-syntax-record.rs b/src/test/compile-fail/removed-syntax-record.rs
index b31e2538ab9..ae5a68575f7 100644
--- a/src/test/compile-fail/removed-syntax-record.rs
+++ b/src/test/compile-fail/removed-syntax-record.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type t = { f: () }; //~ ERROR expected type, found token OpenDelim(Brace)
+type t = { f: () }; //~ ERROR expected type, found `{`
diff --git a/src/test/compile-fail/removed-syntax-uniq-mut-expr.rs b/src/test/compile-fail/removed-syntax-uniq-mut-expr.rs
index 124b3738fab..c5559c4ea96 100644
--- a/src/test/compile-fail/removed-syntax-uniq-mut-expr.rs
+++ b/src/test/compile-fail/removed-syntax-uniq-mut-expr.rs
@@ -11,5 +11,5 @@
 fn f() {
     let a_box = box mut 42;
     //~^  ERROR expected identifier, found keyword `mut`
-    //~^^ ERROR expected `;`, found `42`
+    //~^^ ERROR expected one of `!`, `.`, `::`, `;`, `{`, or an operator, found `42`
 }
diff --git a/src/test/compile-fail/removed-syntax-uniq-mut-ty.rs b/src/test/compile-fail/removed-syntax-uniq-mut-ty.rs
index 579bfed1331..8c3db89bad2 100644
--- a/src/test/compile-fail/removed-syntax-uniq-mut-ty.rs
+++ b/src/test/compile-fail/removed-syntax-uniq-mut-ty.rs
@@ -10,4 +10,4 @@
 
 type mut_box = Box<mut int>;
     //~^  ERROR expected identifier, found keyword `mut`
-    //~^^ ERROR expected `,`, found `int`
+    //~^^ ERROR expected one of `(`, `+`, `,`, `::`, or `>`, found `int`
diff --git a/src/test/compile-fail/removed-syntax-with-1.rs b/src/test/compile-fail/removed-syntax-with-1.rs
index fd8cdb7b10e..c7f31045cb6 100644
--- a/src/test/compile-fail/removed-syntax-with-1.rs
+++ b/src/test/compile-fail/removed-syntax-with-1.rs
@@ -16,5 +16,5 @@ fn removed_with() {
 
     let a = S { foo: (), bar: () };
     let b = S { foo: () with a };
-    //~^ ERROR expected one of `,`, `}`, found `with`
+    //~^ ERROR expected one of `,`, `.`, `}`, or an operator, found `with`
 }
diff --git a/src/test/compile-fail/struct-literal-in-for.rs b/src/test/compile-fail/struct-literal-in-for.rs
index ccd711d8375..a37197b889d 100644
--- a/src/test/compile-fail/struct-literal-in-for.rs
+++ b/src/test/compile-fail/struct-literal-in-for.rs
@@ -20,7 +20,7 @@ impl Foo {
 
 fn main() {
     for x in Foo {
-        x: 3    //~ ERROR expected one of `;`, `}`
+        x: 3    //~ ERROR expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `:`
     }.hi() {
         println!("yo");
     }
diff --git a/src/test/compile-fail/struct-literal-in-if.rs b/src/test/compile-fail/struct-literal-in-if.rs
index d63c216c3be..9759e4f7bda 100644
--- a/src/test/compile-fail/struct-literal-in-if.rs
+++ b/src/test/compile-fail/struct-literal-in-if.rs
@@ -20,7 +20,7 @@ impl Foo {
 
 fn main() {
     if Foo {
-        x: 3    //~ ERROR expected one of `;`, `}`
+        x: 3    //~ ERROR expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `:`
     }.hi() {
         println!("yo");
     }
diff --git a/src/test/compile-fail/struct-literal-in-match-discriminant.rs b/src/test/compile-fail/struct-literal-in-match-discriminant.rs
index c740ba02062..297d3f7347f 100644
--- a/src/test/compile-fail/struct-literal-in-match-discriminant.rs
+++ b/src/test/compile-fail/struct-literal-in-match-discriminant.rs
@@ -14,7 +14,7 @@ struct Foo {
 
 fn main() {
     match Foo {
-        x: 3    //~ ERROR expected `=>`
+        x: 3    //~ ERROR expected one of `!`, `=>`, `@`, or `|`, found `:`
     } {
         Foo {
             x: x
diff --git a/src/test/compile-fail/struct-literal-in-while.rs b/src/test/compile-fail/struct-literal-in-while.rs
index 7b2c11e2597..5b1679cf9a1 100644
--- a/src/test/compile-fail/struct-literal-in-while.rs
+++ b/src/test/compile-fail/struct-literal-in-while.rs
@@ -20,7 +20,7 @@ impl Foo {
 
 fn main() {
     while Foo {
-        x: 3    //~ ERROR expected one of `;`, `}`
+        x: 3    //~ ERROR expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `:`
     }.hi() {
         println!("yo");
     }
diff --git a/src/test/compile-fail/issue-17718-extern-const.rs b/src/test/compile-fail/trailing-comma-array-repeat.rs
index 235d1222d81..dadd6571583 100644
--- a/src/test/compile-fail/issue-17718-extern-const.rs
+++ b/src/test/compile-fail/trailing-comma-array-repeat.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern {
-    const FOO: uint; //~ ERROR: unexpected token: `const`
+fn main() {
+    let [_, ..,] = [(), ()]; //~ ERROR unexpected token: `]`
 }
-
-fn main() {}
diff --git a/src/test/compile-fail/tuple-index-not-tuple.rs b/src/test/compile-fail/tuple-index-not-tuple.rs
index d4ef0e20b26..33aeebb3691 100644
--- a/src/test/compile-fail/tuple-index-not-tuple.rs
+++ b/src/test/compile-fail/tuple-index-not-tuple.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tuple_indexing)]
-
 struct Point { x: int, y: int }
 struct Empty;
 
diff --git a/src/test/compile-fail/tuple-index-out-of-bounds.rs b/src/test/compile-fail/tuple-index-out-of-bounds.rs
index f9bf2746794..609e34f2274 100644
--- a/src/test/compile-fail/tuple-index-out-of-bounds.rs
+++ b/src/test/compile-fail/tuple-index-out-of-bounds.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tuple_indexing)]
-
 struct Point(int, int);
 
 fn main() {
diff --git a/src/test/compile-fail/unresolved-extern-mod-suggestion.rs b/src/test/compile-fail/unresolved-extern-mod-suggestion.rs
index 33d3deb8733..c2ee62c195c 100644
--- a/src/test/compile-fail/unresolved-extern-mod-suggestion.rs
+++ b/src/test/compile-fail/unresolved-extern-mod-suggestion.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 extern crate core;
-use core; //~ ERROR unresolved import (maybe you meant `core::*`?)
+use core;
+//~^ ERROR import `core` conflicts with imported crate in this module
 
 fn main() {}
diff --git a/src/test/compile-fail/while-let.rs b/src/test/compile-fail/while-let.rs
index 0dd442ec3f6..ccf3d2dd750 100644
--- a/src/test/compile-fail/while-let.rs
+++ b/src/test/compile-fail/while-let.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules,while_let)]
+#![feature(macro_rules)]
 
 fn macros() {
     macro_rules! foo{
diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
index 9a42cd92fdc..76cf3c1149d 100644
--- a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
+++ b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
@@ -58,11 +58,17 @@
 // gdb-command: print none
 // gdb-check:$12 = None
 
+// gdb-command: print some_fat
+// gdb-check:$13 = Some = {"abc"}
+
+// gdb-command: print none_fat
+// gdb-check:$14 = None
+
 // gdb-command: print nested_variant1
-// gdb-check:$13 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}
+// gdb-check:$15 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}
 
 // gdb-command: print nested_variant2
-// gdb-check:$14 = NestedVariant2 = {abc = NestedStruct = {regular_struct = RegularStruct = {the_first_field = 117, the_second_field = 118.5, the_third_field = false, the_fourth_field = "NestedStructString10"}, tuple_struct = TupleStruct = {119.5, 120}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar3, mixed_enum = MixedEnumStructVar = {field1 = 121.5, field2 = -122}}}
+// gdb-check:$16 = NestedVariant2 = {abc = NestedStruct = {regular_struct = RegularStruct = {the_first_field = 117, the_second_field = 118.5, the_third_field = false, the_fourth_field = "NestedStructString10"}, tuple_struct = TupleStruct = {119.5, 120}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar3, mixed_enum = MixedEnumStructVar = {field1 = 121.5, field2 = -122}}}
 
 use self::CStyleEnum::{CStyleEnumVar1, CStyleEnumVar2, CStyleEnumVar3};
 use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar};
@@ -129,6 +135,8 @@ fn main() {
 
     let some = Some(110u);
     let none: Option<int> = None;
+    let some_fat = Some("abc");
+    let none_fat: Option<&'static str> = None;
 
     let nested_variant1 = NestedVariant1(
         NestedStruct {
diff --git a/src/test/debuginfo/option-like-enum.rs b/src/test/debuginfo/option-like-enum.rs
index 11c594bac59..333a430e351 100644
--- a/src/test/debuginfo/option-like-enum.rs
+++ b/src/test/debuginfo/option-like-enum.rs
@@ -61,6 +61,12 @@
 // lldb-command:print void_droid
 // lldb-check:[...]$5 = Void
 
+// lldb-command:print some_str
+// lldb-check:[...]$6 = Some(&str { data_ptr: [...], length: 3 })
+
+// lldb-command:print none_str
+// lldb-check:[...]$7 = None
+
 
 // If a struct has exactly two variants, one of them is empty, and the other one
 // contains a non-nullable pointer, then this value is used as the discriminator.
@@ -96,6 +102,9 @@ struct NamedFieldsRepr<'a> {
 
 fn main() {
 
+    let some_str: Option<&'static str> = Some("abc");
+    let none_str: Option<&'static str> = None;
+
     let some: Option<&u32> = Some(unsafe { std::mem::transmute(0x12345678u) });
     let none: Option<&u32> = None;
 
diff --git a/src/test/run-fail/result-get-panic.rs b/src/test/run-fail/result-get-panic.rs
index 6098b97c79a..df14efd6c3a 100644
--- a/src/test/run-fail/result-get-panic.rs
+++ b/src/test/run-fail/result-get-panic.rs
@@ -10,8 +10,8 @@
 
 // error-pattern:called `Result::unwrap()` on an `Err` value
 
-use std::result;
+use std::result::Result::Err;
 
 fn main() {
-    println!("{}", result::Err::<int,String>("kitty".to_string()).unwrap());
+    println!("{}", Err::<int,String>("kitty".to_string()).unwrap());
 }
diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs
index 715fae314b6..8a0c14d2d7e 100644
--- a/src/test/run-make/issue-19371/foo.rs
+++ b/src/test/run-make/issue-19371/foo.rs
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 extern crate rustc;
-extern crate rustc_trans;
+extern crate rustc_driver;
 extern crate syntax;
 
 use rustc::session::{build_session, Session};
-use rustc::session::config::{basic_options, build_configuration, OutputTypeExe};
-use rustc_trans::driver::driver::{Input, StrInput, compile_input};
+use rustc::session::config::{basic_options, build_configuration, Input, OutputTypeExe};
+use rustc_driver::driver::{compile_input};
 use syntax::diagnostics::registry::Registry;
 
 fn main() {
@@ -55,7 +55,7 @@ fn compile(code: String, output: Path, sysroot: Path) {
 
     compile_input(sess,
             cfg,
-            &StrInput(code),
+            &Input::Str(code),
             &None,
             &Some(output),
             None);
diff --git a/src/test/run-pass/deriving-cmp-shortcircuit.rs b/src/test/run-pass/deriving-cmp-shortcircuit.rs
index fd59b804da3..b68d8058381 100644
--- a/src/test/run-pass/deriving-cmp-shortcircuit.rs
+++ b/src/test/run-pass/deriving-cmp-shortcircuit.rs
@@ -39,5 +39,5 @@ pub fn main() {
 
     assert!(a != b);
     assert!(a < b);
-    assert_eq!(a.cmp(&b), ::std::cmp::Less);
+    assert_eq!(a.cmp(&b), ::std::cmp::Ordering::Less);
 }
diff --git a/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs b/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs
index 1187a9a8bc4..d63c264479a 100644
--- a/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs
+++ b/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs
@@ -10,7 +10,7 @@
 
 // ignore-test FIXME #11820: & is unreliable in deriving
 
-use std::cmp::{Less,Equal,Greater};
+use std::cmp::Ordering::{Less,Equal,Greater};
 
 #[deriving(Eq,Ord)]
 struct A<'a> {
diff --git a/src/test/run-pass/enum-nullable-const-null-with-fields.rs b/src/test/run-pass/enum-nullable-const-null-with-fields.rs
index a48f3bcd59c..4b839d740fc 100644
--- a/src/test/run-pass/enum-nullable-const-null-with-fields.rs
+++ b/src/test/run-pass/enum-nullable-const-null-with-fields.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::result::{Result,Ok};
+use std::result::Result;
+use std::result::Result::Ok;
 
 static C: Result<(), Box<int>> = Ok(());
 
diff --git a/src/test/run-pass/issue-13304.rs b/src/test/run-pass/issue-13304.rs
index 047ff74035b..11003c6fc52 100644
--- a/src/test/run-pass/issue-13304.rs
+++ b/src/test/run-pass/issue-13304.rs
@@ -37,7 +37,7 @@ fn parent() {
 }
 
 fn child() {
-    for line in io::stdin().lines() {
+    for line in io::stdin().lock().lines() {
         println!("{}", line.unwrap());
     }
 }
diff --git a/src/test/run-pass/issue-14456.rs b/src/test/run-pass/issue-14456.rs
index 2339e3f6302..f5fdf8704ed 100644
--- a/src/test/run-pass/issue-14456.rs
+++ b/src/test/run-pass/issue-14456.rs
@@ -27,7 +27,7 @@ fn main() {
 fn child() {
     io::stdout().write_line("foo").unwrap();
     io::stderr().write_line("bar").unwrap();
-    assert_eq!(io::stdin().read_line().err().unwrap().kind, io::EndOfFile);
+    assert_eq!(io::stdin().lock().read_line().err().unwrap().kind, io::EndOfFile);
 }
 
 fn test() {
diff --git a/src/test/run-pass/issue-16671.rs b/src/test/run-pass/issue-16671.rs
index a0d384418f9..20bf1b260de 100644
--- a/src/test/run-pass/issue-16671.rs
+++ b/src/test/run-pass/issue-16671.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-android seems to block forever
+
 #![forbid(warnings)]
 
 // Pretty printing tests complain about `use std::predule::*`
@@ -19,6 +21,6 @@
 pub fn main() {
     let mut stdin = std::io::stdin();
     spawn(proc() {
-        let _ = stdin.lines();
+        let _ = stdin.read_to_end();
     });
 }
diff --git a/src/test/run-pass/issue-2804.rs b/src/test/run-pass/issue-2804.rs
index ec19b95ab1a..6f1f2cea8ec 100644
--- a/src/test/run-pass/issue-2804.rs
+++ b/src/test/run-pass/issue-2804.rs
@@ -24,14 +24,14 @@ enum object {
 fn lookup(table: json::Object, key: String, default: String) -> String
 {
     match table.find(&key.to_string()) {
-        option::Some(&Json::String(ref s)) => {
+        option::Option::Some(&Json::String(ref s)) => {
             s.to_string()
         }
-        option::Some(value) => {
+        option::Option::Some(value) => {
             println!("{} was expected to be a string but is a {}", key, value);
             default
         }
-        option::None => {
+        option::Option::None => {
             default
         }
     }
diff --git a/src/test/run-pass/issue-3424.rs b/src/test/run-pass/issue-3424.rs
index 2dac64b2ec8..81efacb9bcb 100644
--- a/src/test/run-pass/issue-3424.rs
+++ b/src/test/run-pass/issue-3424.rs
@@ -20,7 +20,7 @@ type rsrc_loader = proc(path: &Path):'static -> result::Result<String, String>;
 fn tester()
 {
     let loader: rsrc_loader = proc(_path) {
-        result::Ok("more blah".to_string())
+        result::Result::Ok("more blah".to_string())
     };
 
     let path = path::Path::new("blah");
diff --git a/src/test/run-pass/new-unicode-escapes.rs b/src/test/run-pass/new-unicode-escapes.rs
new file mode 100644
index 00000000000..2888389bcce
--- /dev/null
+++ b/src/test/run-pass/new-unicode-escapes.rs
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    let s = "\u{2603}";
+    assert_eq!(s, "☃");
+
+    let s = "\u{2a10}\u{2A01}\u{2Aa0}";
+    assert_eq!(s, "⨐⨁⪠");
+
+    let s = "\\{20}";
+    let mut correct_s = String::from_str("\\");
+    correct_s.push_str("{20}");
+    assert_eq!(s, correct_s.as_slice());
+}
diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs
index 520d067bca3..da1ad094df6 100644
--- a/src/test/run-pass/nullable-pointer-iotareduction.rs
+++ b/src/test/run-pass/nullable-pointer-iotareduction.rs
@@ -41,9 +41,9 @@ macro_rules! check_option {
         check_option!($e: $T, |ptr| assert!(*ptr == $e));
     }};
     ($e:expr: $T:ty, |$v:ident| $chk:expr) => {{
-        assert!(option::None::<$T>.is_none());
+        assert!(option::Option::None::<$T>.is_none());
         let e = $e;
-        let s_ = option::Some::<$T>(e);
+        let s_ = option::Option::Some::<$T>(e);
         let $v = s_.as_ref().unwrap();
         $chk
     }}
diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs
index ef485723c7e..1b0f2ec0a32 100644
--- a/src/test/run-pass/send_str_hashmap.rs
+++ b/src/test/run-pass/send_str_hashmap.rs
@@ -11,7 +11,7 @@
 extern crate collections;
 
 use std::collections::HashMap;
-use std::option::Some;
+use std::option::Option::Some;
 use std::str::SendStr;
 
 pub fn main() {
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index f72ca109b6e..9334b673b51 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -11,7 +11,7 @@
 extern crate collections;
 
 use self::collections::TreeMap;
-use std::option::Some;
+use std::option::Option::Some;
 use std::str::SendStr;
 use std::string::ToString;
 
diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs
index 5e93f8eedb7..00e05064080 100644
--- a/src/test/run-pass/trailing-comma.rs
+++ b/src/test/run-pass/trailing-comma.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(advanced_slice_patterns,)]
+
 fn f<T,>(_: T,) {}
 
 struct Foo<T,>;
@@ -24,9 +26,13 @@ enum Baz {
     Qux(int,),
 }
 
+#[allow(unused,)]
 pub fn main() {
     f::<int,>(0i,);
     let (_, _,) = (1i, 1i,);
+    let [_, _,] = [1i, 1,];
+    let [_, _, .., _,] = [1i, 1, 1, 1,];
+    let [_, _, _.., _,] = [1i, 1, 1, 1,];
 
     let x: Foo<int,> = Foo::<int,>;
 
diff --git a/src/test/run-pass/wait-forked-but-failed-child.rs b/src/test/run-pass/wait-forked-but-failed-child.rs
new file mode 100644
index 00000000000..f482b2e1e70
--- /dev/null
+++ b/src/test/run-pass/wait-forked-but-failed-child.rs
@@ -0,0 +1,80 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test
+
+extern crate libc;
+
+use std::io::process::Command;
+use std::iter::IteratorExt;
+
+use libc::funcs::posix88::unistd;
+
+
+// "ps -A -o pid,sid,command" with GNU ps should output something like this:
+//   PID   SID COMMAND
+//     1     1 /sbin/init
+//     2     0 [kthreadd]
+//     3     0 [ksoftirqd/0]
+// ...
+// 12562  9237 ./spawn-failure
+// 12563  9237 [spawn-failure] <defunct>
+// 12564  9237 [spawn-failure] <defunct>
+// ...
+// 12592  9237 [spawn-failure] <defunct>
+// 12593  9237 ps -A -o pid,sid,command
+// 12884 12884 /bin/zsh
+// 12922 12922 /bin/zsh
+// ...
+
+#[cfg(unix)]
+fn find_zombies() {
+    // http://man.freebsd.org/ps(1)
+    // http://man7.org/linux/man-pages/man1/ps.1.html
+    #[cfg(not(target_os = "macos"))]
+    const FIELDS: &'static str = "pid,sid,command";
+
+    // https://developer.apple.com/library/mac/documentation/Darwin/
+    // Reference/ManPages/man1/ps.1.html
+    #[cfg(target_os = "macos")]
+    const FIELDS: &'static str = "pid,sess,command";
+
+    let my_sid = unsafe { unistd::getsid(0) };
+
+    let ps_cmd_output = Command::new("ps").args(&["-A", "-o", FIELDS]).output().unwrap();
+    let ps_output = String::from_utf8_lossy(ps_cmd_output.output.as_slice());
+
+    let found = ps_output.split('\n').enumerate().any(|(line_no, line)|
+        0 < line_no && 0 < line.len() &&
+        my_sid == from_str(line.split(' ').filter(|w| 0 < w.len()).nth(1)
+            .expect("1st column should be Session ID")
+            ).expect("Session ID string into integer") &&
+        line.contains("defunct") && {
+            println!("Zombie child {}", line);
+            true
+        }
+    );
+
+    assert!( ! found, "Found at least one zombie child");
+}
+
+#[cfg(windows)]
+fn find_zombies() { }
+
+fn main() {
+    let too_long = format!("/NoSuchCommand{:0300}", 0u8);
+
+    for _ in range(0u32, 100) {
+        let invalid = Command::new(too_long.as_slice()).spawn();
+        assert!(invalid.is_err());
+    }
+
+    find_zombies();
+}