about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-01-02 21:56:13 +0000
committerbors <bors@rust-lang.org>2015-01-02 21:56:13 +0000
commitc89417130f042c58adc60012e7cddc4ef70b70b9 (patch)
tree344f3d621e187b41d23ef01f621ff68ebe810a03
parent4b40bc85cbc1d072179c92ce01655db0272aa598 (diff)
parent340f3fd7a909b30509a63916df06f2b885d113f7 (diff)
downloadrust-c89417130f042c58adc60012e7cddc4ef70b70b9.tar.gz
rust-c89417130f042c58adc60012e7cddc4ef70b70b9.zip
auto merge of #20436 : alexcrichton/rust/rollup, r=alexcrichton
-rw-r--r--.travis.yml1
-rw-r--r--mk/dist.mk4
-rw-r--r--mk/install.mk4
-rw-r--r--src/compiletest/compiletest.rs4
-rw-r--r--src/doc/guide-ffi.md2
-rw-r--r--src/doc/guide-tasks.md2
-rw-r--r--src/doc/guide.md482
-rw-r--r--src/doc/reference.md11
-rw-r--r--src/etc/licenseck.py4
-rw-r--r--src/liballoc/arc.rs10
-rw-r--r--src/liballoc/boxed.rs20
-rw-r--r--src/liballoc/lib.rs4
-rw-r--r--src/liballoc/rc.rs4
-rw-r--r--src/libcollections/binary_heap.rs2
-rw-r--r--src/libcollections/bit.rs13
-rw-r--r--src/libcollections/btree/map.rs25
-rw-r--r--src/libcollections/btree/node.rs54
-rw-r--r--src/libcollections/btree/set.rs11
-rw-r--r--src/libcollections/dlist.rs5
-rw-r--r--src/libcollections/enum_set.rs2
-rw-r--r--src/libcollections/lib.rs5
-rw-r--r--src/libcollections/ring_buf.rs8
-rw-r--r--src/libcollections/slice.rs511
-rw-r--r--src/libcollections/string.rs40
-rw-r--r--src/libcollections/vec.rs26
-rw-r--r--src/libcollections/vec_map.rs4
-rw-r--r--src/libcore/array.rs4
-rw-r--r--src/libcore/atomic.rs16
-rw-r--r--src/libcore/borrow.rs4
-rw-r--r--src/libcore/cell.rs12
-rw-r--r--src/libcore/clone.rs2
-rw-r--r--src/libcore/cmp.rs5
-rw-r--r--src/libcore/fmt/float.rs20
-rw-r--r--src/libcore/fmt/mod.rs95
-rw-r--r--src/libcore/fmt/num.rs4
-rw-r--r--src/libcore/iter.rs21
-rw-r--r--src/libcore/nonzero.rs4
-rw-r--r--src/libcore/num/mod.rs2
-rw-r--r--src/libcore/ops.rs80
-rw-r--r--src/libcore/option.rs2
-rw-r--r--src/libcore/prelude.rs32
-rw-r--r--src/libcore/ptr.rs26
-rw-r--r--src/libcore/slice.rs319
-rw-r--r--src/libcore/tuple.rs29
-rw-r--r--src/libcoretest/atomic.rs6
-rw-r--r--src/libcoretest/cmp.rs3
-rw-r--r--src/libcoretest/iter.rs1
-rw-r--r--src/libcoretest/num/int_macros.rs1
-rw-r--r--src/libcoretest/num/mod.rs2
-rw-r--r--src/libcoretest/num/uint_macros.rs1
-rw-r--r--src/libcoretest/str.rs2
-rw-r--r--src/libcoretest/tuple.rs2
-rw-r--r--src/libgraphviz/lib.rs5
-rw-r--r--src/libgraphviz/maybe_owned_vec.rs10
-rw-r--r--src/liblog/lib.rs2
-rw-r--r--src/librand/chacha.rs2
-rw-r--r--src/librand/distributions/exponential.rs4
-rw-r--r--src/librand/distributions/gamma.rs4
-rw-r--r--src/librand/distributions/mod.rs2
-rw-r--r--src/librand/distributions/normal.rs4
-rw-r--r--src/librand/distributions/range.rs2
-rw-r--r--src/librand/isaac.rs2
-rw-r--r--src/librand/lib.rs4
-rw-r--r--src/librand/rand_impls.rs2
-rw-r--r--src/librand/reseeding.rs2
-rw-r--r--src/libregex/re.rs1
-rw-r--r--src/libregex/vm.rs1
-rw-r--r--src/librustc/lib.rs3
-rw-r--r--src/librustc/lint/builtin.rs3
-rw-r--r--src/librustc/metadata/decoder.rs22
-rw-r--r--src/librustc/metadata/encoder.rs9
-rw-r--r--src/librustc/metadata/tydecode.rs1
-rw-r--r--src/librustc/middle/cfg/graphviz.rs4
-rw-r--r--src/librustc/middle/check_match.rs3
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc/middle/infer/combine.rs2
-rw-r--r--src/librustc/middle/infer/region_inference/graphviz.rs2
-rw-r--r--src/librustc/middle/infer/region_inference/mod.rs3
-rw-r--r--src/librustc/middle/lang_items.rs1
-rw-r--r--src/librustc/middle/region.rs5
-rw-r--r--src/librustc/middle/stability.rs15
-rw-r--r--src/librustc/middle/subst.rs2
-rw-r--r--src/librustc/middle/traits/coherence.rs153
-rw-r--r--src/librustc/middle/traits/mod.rs27
-rw-r--r--src/librustc/middle/traits/object_safety.rs301
-rw-r--r--src/librustc/middle/traits/project.rs82
-rw-r--r--src/librustc/middle/traits/select.rs175
-rw-r--r--src/librustc/middle/traits/util.rs69
-rw-r--r--src/librustc/middle/ty.rs146
-rw-r--r--src/librustc/middle/ty_fold.rs11
-rw-r--r--src/librustc/middle/ty_walk.rs112
-rw-r--r--src/librustc/session/config.rs21
-rw-r--r--src/librustc/session/search_paths.rs17
-rw-r--r--src/librustc_back/lib.rs1
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/move_error.rs2
-rw-r--r--src/librustc_borrowck/graphviz.rs1
-rw-r--r--src/librustc_borrowck/lib.rs2
-rw-r--r--src/librustc_driver/driver.rs12
-rw-r--r--src/librustc_driver/lib.rs2
-rw-r--r--src/librustc_driver/pretty.rs10
-rw-r--r--src/librustc_driver/test.rs56
-rw-r--r--src/librustc_llvm/archive_ro.rs3
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs9
-rw-r--r--src/librustc_resolve/check_unused.rs8
-rw-r--r--src/librustc_resolve/lib.rs5
-rw-r--r--src/librustc_resolve/record_exports.rs7
-rw-r--r--src/librustc_trans/back/lto.rs1
-rw-r--r--src/librustc_trans/back/write.rs7
-rw-r--r--src/librustc_trans/lib.rs2
-rw-r--r--src/librustc_trans/save/mod.rs5
-rw-r--r--src/librustc_trans/trans/base.rs2
-rw-r--r--src/librustc_trans/trans/builder.rs2
-rw-r--r--src/librustc_trans/trans/debuginfo.rs10
-rw-r--r--src/librustc_trans/trans/foreign.rs1
-rw-r--r--src/librustc_trans/trans/meth.rs151
-rw-r--r--src/librustc_typeck/check/method/confirm.rs17
-rw-r--r--src/librustc_typeck/check/method/probe.rs39
-rw-r--r--src/librustc_typeck/check/mod.rs6
-rw-r--r--src/librustc_typeck/check/vtable.rs276
-rw-r--r--src/librustc_typeck/coherence/orphan.rs32
-rw-r--r--src/librustc_typeck/collect.rs27
-rw-r--r--src/librustdoc/flock.rs2
-rw-r--r--src/librustdoc/fold.rs2
-rw-r--r--src/librustdoc/html/escape.rs6
-rw-r--r--src/librustdoc/html/format.rs58
-rw-r--r--src/librustdoc/html/markdown.rs5
-rw-r--r--src/librustdoc/html/render.rs48
-rw-r--r--src/librustdoc/lib.rs14
-rw-r--r--src/librustdoc/stability_summary.rs3
-rw-r--r--src/librustdoc/test.rs4
-rw-r--r--src/libserialize/json.rs290
-rw-r--r--src/libstd/ascii.rs2
-rw-r--r--src/libstd/bitflags.rs11
-rw-r--r--src/libstd/c_str.rs19
-rw-r--r--src/libstd/c_vec.rs4
-rw-r--r--src/libstd/collections/hash/bench.rs2
-rw-r--r--src/libstd/collections/hash/map.rs10
-rw-r--r--src/libstd/collections/hash/set.rs2
-rw-r--r--src/libstd/collections/hash/table.rs16
-rw-r--r--src/libstd/dynamic_lib.rs10
-rw-r--r--src/libstd/error.rs2
-rw-r--r--src/libstd/failure.rs8
-rw-r--r--src/libstd/fmt.rs23
-rw-r--r--src/libstd/io/buffered.rs10
-rw-r--r--src/libstd/io/comm_adapters.rs40
-rw-r--r--src/libstd/io/extensions.rs4
-rw-r--r--src/libstd/io/fs.rs2
-rw-r--r--src/libstd/io/mem.rs5
-rw-r--r--src/libstd/io/mod.rs39
-rw-r--r--src/libstd/io/net/addrinfo.rs2
-rw-r--r--src/libstd/io/net/ip.rs4
-rw-r--r--src/libstd/io/net/pipe.rs164
-rw-r--r--src/libstd/io/net/tcp.rs257
-rw-r--r--src/libstd/io/net/udp.rs103
-rw-r--r--src/libstd/io/pipe.rs13
-rw-r--r--src/libstd/io/process.rs61
-rw-r--r--src/libstd/io/result.rs2
-rw-r--r--src/libstd/io/stdio.rs17
-rw-r--r--src/libstd/io/tempfile.rs2
-rw-r--r--src/libstd/io/test.rs9
-rw-r--r--src/libstd/io/timer.rs101
-rw-r--r--src/libstd/io/util.rs8
-rw-r--r--src/libstd/lib.rs6
-rw-r--r--src/libstd/macros.rs12
-rw-r--r--src/libstd/num/f32.rs38
-rw-r--r--src/libstd/num/f64.rs37
-rw-r--r--src/libstd/num/mod.rs8
-rw-r--r--src/libstd/num/strconv.rs2
-rw-r--r--src/libstd/num/uint_macros.rs3
-rw-r--r--src/libstd/os.rs28
-rw-r--r--src/libstd/path/mod.rs7
-rw-r--r--src/libstd/path/posix.rs18
-rw-r--r--src/libstd/path/windows.rs14
-rw-r--r--src/libstd/prelude.rs94
-rw-r--r--src/libstd/prelude/mod.rs42
-rw-r--r--src/libstd/prelude/v1.rs49
-rw-r--r--src/libstd/rand/mod.rs4
-rw-r--r--src/libstd/rand/os.rs15
-rw-r--r--src/libstd/rand/reader.rs2
-rw-r--r--src/libstd/rt/args.rs4
-rw-r--r--src/libstd/rt/backtrace.rs6
-rw-r--r--src/libstd/rt/exclusive.rs119
-rw-r--r--src/libstd/rt/mod.rs13
-rw-r--r--src/libstd/rt/task.rs554
-rw-r--r--src/libstd/rt/unwind.rs41
-rw-r--r--src/libstd/rt/util.rs25
-rw-r--r--src/libstd/sync/atomic.rs10
-rw-r--r--src/libstd/sync/barrier.rs64
-rw-r--r--src/libstd/sync/condvar.rs31
-rw-r--r--src/libstd/sync/future.rs30
-rw-r--r--src/libstd/sync/mod.rs4
-rw-r--r--src/libstd/sync/mpsc/blocking.rs (renamed from src/libstd/comm/blocking.rs)4
-rw-r--r--src/libstd/sync/mpsc/mod.rs (renamed from src/libstd/comm/mod.rs)1418
-rw-r--r--src/libstd/sync/mpsc/mpsc_queue.rs (renamed from src/libstd/comm/mpsc_queue.rs)15
-rw-r--r--src/libstd/sync/mpsc/oneshot.rs (renamed from src/libstd/comm/oneshot.rs)4
-rw-r--r--src/libstd/sync/mpsc/select.rs (renamed from src/libstd/comm/select.rs)343
-rw-r--r--src/libstd/sync/mpsc/shared.rs (renamed from src/libstd/comm/shared.rs)8
-rw-r--r--src/libstd/sync/mpsc/spsc_queue.rs (renamed from src/libstd/comm/spsc_queue.rs)10
-rw-r--r--src/libstd/sync/mpsc/stream.rs (renamed from src/libstd/comm/stream.rs)6
-rw-r--r--src/libstd/sync/mpsc/sync.rs (renamed from src/libstd/comm/sync.rs)10
-rw-r--r--src/libstd/sync/mutex.rs48
-rw-r--r--src/libstd/sync/once.rs44
-rw-r--r--src/libstd/sync/poison.rs2
-rw-r--r--src/libstd/sync/rwlock.rs26
-rw-r--r--src/libstd/sync/semaphore.rs37
-rw-r--r--src/libstd/sync/task_pool.rs27
-rw-r--r--src/libstd/sys/common/backtrace.rs2
-rw-r--r--src/libstd/sys/common/helper_thread.rs7
-rw-r--r--src/libstd/sys/common/mod.rs2
-rw-r--r--src/libstd/sys/common/net.rs12
-rw-r--r--src/libstd/sys/common/thread_info.rs5
-rw-r--r--src/libstd/sys/common/thread_local.rs6
-rw-r--r--src/libstd/sys/unix/fs.rs13
-rw-r--r--src/libstd/sys/unix/mod.rs2
-rw-r--r--src/libstd/sys/unix/os.rs9
-rw-r--r--src/libstd/sys/unix/pipe.rs13
-rw-r--r--src/libstd/sys/unix/process.rs33
-rw-r--r--src/libstd/sys/unix/tcp.rs3
-rw-r--r--src/libstd/sys/unix/thread_local.rs2
-rw-r--r--src/libstd/sys/unix/timer.rs16
-rw-r--r--src/libstd/sys/unix/tty.rs3
-rw-r--r--src/libstd/sys/windows/c.rs5
-rw-r--r--src/libstd/sys/windows/fs.rs2
-rw-r--r--src/libstd/sys/windows/mod.rs7
-rw-r--r--src/libstd/sys/windows/mutex.rs4
-rw-r--r--src/libstd/sys/windows/os.rs2
-rw-r--r--src/libstd/sys/windows/pipe.rs6
-rw-r--r--src/libstd/sys/windows/process.rs8
-rw-r--r--src/libstd/sys/windows/tcp.rs2
-rw-r--r--src/libstd/sys/windows/thread_local.rs2
-rw-r--r--src/libstd/sys/windows/timer.rs12
-rw-r--r--src/libstd/sys/windows/tty.rs19
-rw-r--r--src/libstd/thread.rs22
-rw-r--r--src/libstd/thread_local/mod.rs190
-rw-r--r--src/libstd/thread_local/scoped.rs29
-rw-r--r--src/libstd/time/mod.rs2
-rw-r--r--src/libstd/tuple.rs6
-rw-r--r--src/libsyntax/ast.rs5
-rw-r--r--src/libsyntax/codemap.rs19
-rw-r--r--src/libsyntax/ext/build.rs4
-rw-r--r--src/libsyntax/ext/bytes.rs1
-rw-r--r--src/libsyntax/ext/expand.rs2
-rw-r--r--src/libsyntax/ext/quote.rs3
-rw-r--r--src/libsyntax/feature_gate.rs36
-rw-r--r--src/libsyntax/fold.rs4
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax/owned_slice.rs8
-rw-r--r--src/libsyntax/parse/lexer/mod.rs3
-rw-r--r--src/libsyntax/parse/parser.rs11
-rw-r--r--src/libsyntax/parse/token.rs6
-rw-r--r--src/libsyntax/print/pprust.rs10
-rw-r--r--src/libsyntax/ptr.rs24
-rw-r--r--src/libsyntax/std_inject.rs9
-rw-r--r--src/libsyntax/util/interner.rs8
-rw-r--r--src/libsyntax/util/small_vector.rs2
-rw-r--r--src/libsyntax/visit.rs17
-rw-r--r--src/libtest/lib.rs48
-rw-r--r--src/libtest/stats.rs5
-rw-r--r--src/libtime/lib.rs11
-rw-r--r--src/snapshots.txt9
-rw-r--r--src/test/auxiliary/cci_capture_clause.rs1
-rw-r--r--src/test/auxiliary/coherence-lib.rs25
-rw-r--r--src/test/auxiliary/issue-17718.rs4
-rw-r--r--src/test/auxiliary/issue_20389.rs (renamed from src/test/bench/spawnone.rs)9
-rw-r--r--src/test/auxiliary/method_self_arg2.rs2
-rw-r--r--src/test/auxiliary/overloaded_autoderef_xc.rs6
-rw-r--r--src/test/auxiliary/static-methods-crate.rs1
-rw-r--r--src/test/auxiliary/trait_inheritance_overloading_xc.rs1
-rw-r--r--src/test/auxiliary/traitimpl.rs17
-rw-r--r--src/test/auxiliary/unboxed-closures-cross-crate.rs2
-rw-r--r--src/test/bench/core-map.rs1
-rw-r--r--src/test/bench/core-set.rs3
-rw-r--r--src/test/bench/core-uint-to-str.rs1
-rw-r--r--src/test/bench/msgsend-pipes-shared.rs15
-rw-r--r--src/test/bench/msgsend-pipes.rs9
-rw-r--r--src/test/bench/msgsend-ring-mutex-arcs.rs1
-rw-r--r--src/test/bench/rt-messaging-ping-pong.rs11
-rw-r--r--src/test/bench/rt-parfib.rs10
-rw-r--r--src/test/bench/shootout-ackermann.rs1
-rw-r--r--src/test/bench/shootout-binarytrees.rs12
-rw-r--r--src/test/bench/shootout-chameneos-redux.rs20
-rw-r--r--src/test/bench/shootout-fannkuch-redux.rs10
-rw-r--r--src/test/bench/shootout-fasta-redux.rs1
-rw-r--r--src/test/bench/shootout-fasta.rs5
-rw-r--r--src/test/bench/shootout-fibo.rs1
-rw-r--r--src/test/bench/shootout-k-nucleotide-pipes.rs13
-rw-r--r--src/test/bench/shootout-k-nucleotide.rs1
-rw-r--r--src/test/bench/shootout-mandelbrot.rs1
-rw-r--r--src/test/bench/shootout-meteor.rs10
-rw-r--r--src/test/bench/shootout-nbody.rs1
-rw-r--r--src/test/bench/shootout-pfib.rs10
-rw-r--r--src/test/bench/shootout-reverse-complement.rs19
-rw-r--r--src/test/bench/shootout-spectralnorm.rs29
-rw-r--r--src/test/bench/shootout-threadring.rs8
-rw-r--r--src/test/bench/std-smallintmap.rs1
-rw-r--r--src/test/bench/sudoku.rs5
-rw-r--r--src/test/bench/task-perf-jargon-metal-smoke.rs14
-rw-r--r--src/test/bench/task-perf-spawnalot.rs1
-rw-r--r--src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs34
-rw-r--r--src/test/compile-fail/bind-by-move-no-guards.rs7
-rw-r--r--src/test/compile-fail/binop-consume-args.rs2
-rw-r--r--src/test/compile-fail/binop-move-semantics.rs2
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs8
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs6
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs8
-rw-r--r--src/test/compile-fail/borrowck-borrow-overloaded-deref.rs6
-rw-r--r--src/test/compile-fail/borrowck-loan-in-overloaded-op.rs1
-rw-r--r--src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs2
-rw-r--r--src/test/compile-fail/borrowck-overloaded-index-2.rs2
-rw-r--r--src/test/compile-fail/borrowck-overloaded-index-autoderef.rs2
-rw-r--r--src/test/compile-fail/borrowck-overloaded-index.rs2
-rw-r--r--src/test/compile-fail/builtin-superkinds-self-type.rs2
-rw-r--r--src/test/compile-fail/coherence-all-remote.rs19
-rw-r--r--src/test/compile-fail/coherence-bigint-param.rs21
-rw-r--r--src/test/compile-fail/coherence-iterator-vec-any-elem.rs21
-rw-r--r--src/test/compile-fail/coherence-lone-type-parameter.rs18
-rw-r--r--src/test/compile-fail/coherence-overlapping-pairs.rs21
-rw-r--r--src/test/compile-fail/coherence-pair-covered-uncovered.rs21
-rw-r--r--src/test/compile-fail/comm-not-freeze-receiver.rs2
-rw-r--r--src/test/compile-fail/comm-not-freeze.rs2
-rw-r--r--src/test/compile-fail/dst-sized-trait-param.rs2
-rw-r--r--src/test/compile-fail/infinite-autoderef.rs6
-rw-r--r--src/test/compile-fail/issue-12041.rs5
-rw-r--r--src/test/compile-fail/issue-16709.rs2
-rw-r--r--src/test/compile-fail/issue-18566.rs8
-rw-r--r--src/test/compile-fail/issue-18819.rs (renamed from src/test/run-fail/panic-non-utf8.rs)27
-rw-r--r--src/test/compile-fail/issue-18959.rs2
-rw-r--r--src/test/compile-fail/issue-19883.rs35
-rw-r--r--src/test/compile-fail/issue-20005.rs29
-rw-r--r--src/test/compile-fail/issue-20313.rs17
-rw-r--r--src/test/compile-fail/issue-3702-2.rs2
-rw-r--r--src/test/compile-fail/issue-5543.rs1
-rw-r--r--src/test/compile-fail/object-safety-by-value-self.rs47
-rw-r--r--src/test/compile-fail/object-safety-generics.rs31
-rw-r--r--src/test/compile-fail/object-safety-mentions-Self.rs47
-rw-r--r--src/test/compile-fail/object-safety-no-static.rs31
-rw-r--r--src/test/compile-fail/object-safety-sized-2.rs33
-rw-r--r--src/test/compile-fail/object-safety-sized.rs31
-rw-r--r--src/test/compile-fail/opt-out-copy-bad.rs2
-rw-r--r--src/test/compile-fail/regions-infer-bound-from-trait-self.rs10
-rw-r--r--src/test/compile-fail/std-uncopyable-atomics.rs6
-rw-r--r--src/test/compile-fail/trait-matching-lifetimes.rs2
-rw-r--r--src/test/compile-fail/trait-objects.rs43
-rw-r--r--src/test/compile-fail/trait-safety-fn-body.rs2
-rw-r--r--src/test/compile-fail/type-params-in-different-spaces-2.rs2
-rw-r--r--src/test/compile-fail/type-params-in-different-spaces-3.rs2
-rw-r--r--src/test/compile-fail/unop-move-semantics.rs2
-rw-r--r--src/test/compile-fail/unsendable-class.rs1
-rw-r--r--src/test/compile-fail/unsized4.rs3
-rw-r--r--src/test/compile-fail/variance-trait-matching-2.rs10
-rw-r--r--src/test/compile-fail/wrong-mul-method-signature.rs2
-rw-r--r--src/test/debuginfo/issue7712.rs2
-rw-r--r--src/test/debuginfo/self-in-default-method.rs2
-rw-r--r--src/test/debuginfo/self-in-generic-default-method.rs2
-rw-r--r--src/test/debuginfo/unreachable-locals.rs86
-rw-r--r--src/test/pretty/issue-4264.pp2
-rw-r--r--src/test/pretty/let.rs (renamed from src/test/run-pass/issue-7320.rs)11
-rw-r--r--src/test/run-make/compiler-lookup-paths/Makefile34
-rw-r--r--src/test/run-make/manual-link/Makefile2
-rw-r--r--src/test/run-pass/associated-types-conditional-dispatch.rs73
-rw-r--r--src/test/run-pass/associated-types-impl-redirect.rs3
-rw-r--r--src/test/run-pass/associated-types-projection-bound-in-supertraits.rs2
-rw-r--r--src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs3
-rw-r--r--src/test/run-pass/bool.rs3
-rw-r--r--src/test/run-pass/bug-7183-generics.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities-transitive.rs6
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities-xc.rs6
-rw-r--r--src/test/run-pass/builtin-superkinds-capabilities.rs6
-rw-r--r--src/test/run-pass/builtin-superkinds-self-type.rs8
-rw-r--r--src/test/run-pass/c-stack-returning-int64.rs2
-rw-r--r--src/test/run-pass/capturing-logging.rs4
-rw-r--r--src/test/run-pass/cci_capture_clause.rs2
-rw-r--r--src/test/run-pass/closure-bounds-can-capture-chan.rs6
-rw-r--r--src/test/run-pass/cmp-default.rs2
-rw-r--r--src/test/run-pass/coherence-bigint-int.rs20
-rw-r--r--src/test/run-pass/coherence-bigint-vecint.rs20
-rw-r--r--src/test/run-pass/coherence-blanket.rs (renamed from src/test/run-pass/trait-object-safety.rs)20
-rw-r--r--src/test/run-pass/coherence-covered-type-parameter.rs20
-rw-r--r--src/test/run-pass/coherence-iterator-vec.rs20
-rw-r--r--src/test/run-pass/coherence-local-1.rs20
-rw-r--r--src/test/run-pass/coherence-local-2.rs20
-rw-r--r--src/test/run-pass/colorful-write-macros.rs10
-rw-r--r--src/test/run-pass/comm.rs5
-rw-r--r--src/test/run-pass/const-str-ptr.rs1
-rw-r--r--src/test/run-pass/core-run-destroy.rs12
-rw-r--r--src/test/run-pass/default-method-supertrait-vtable.rs2
-rw-r--r--src/test/run-pass/deref-mut-on-ref.rs4
-rw-r--r--src/test/run-pass/deref-on-ref.rs4
-rw-r--r--src/test/run-pass/deriving-cmp-shortcircuit.rs2
-rw-r--r--src/test/run-pass/deriving-encodable-decodable-box.rs2
-rw-r--r--src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs2
-rw-r--r--src/test/run-pass/deriving-global.rs2
-rw-r--r--src/test/run-pass/deriving-zero.rs2
-rw-r--r--src/test/run-pass/drop-trait-enum.rs35
-rw-r--r--src/test/run-pass/dst-deref-mut.rs10
-rw-r--r--src/test/run-pass/dst-deref.rs8
-rw-r--r--src/test/run-pass/fixup-deref-mut.rs10
-rw-r--r--src/test/run-pass/foreign-fn-linkname.rs4
-rw-r--r--src/test/run-pass/hashmap-memory.rs14
-rw-r--r--src/test/run-pass/ifmt.rs24
-rw-r--r--src/test/run-pass/issue-11881.rs18
-rw-r--r--src/test/run-pass/issue-13264.rs12
-rw-r--r--src/test/run-pass/issue-13494.rs13
-rw-r--r--src/test/run-pass/issue-14021.rs1
-rw-r--r--src/test/run-pass/issue-15734.rs6
-rw-r--r--src/test/run-pass/issue-15924.rs4
-rw-r--r--src/test/run-pass/issue-16560.rs5
-rw-r--r--src/test/run-pass/issue-16774.rs10
-rw-r--r--src/test/run-pass/issue-17718.rs4
-rw-r--r--src/test/run-pass/issue-17732.rs18
-rw-r--r--src/test/run-pass/issue-19479.rs23
-rw-r--r--src/test/run-pass/issue-19631.rs23
-rw-r--r--src/test/run-pass/issue-19632.rs21
-rw-r--r--src/test/run-pass/issue-19850.rs30
-rw-r--r--src/test/run-pass/issue-20009.rs22
-rw-r--r--src/test/run-pass/issue-20313.rs18
-rw-r--r--src/test/run-pass/issue-20389.rs22
-rw-r--r--src/test/run-pass/issue-3609.rs1
-rw-r--r--src/test/run-pass/issue-3743.rs6
-rw-r--r--src/test/run-pass/issue-3979-generics.rs2
-rw-r--r--src/test/run-pass/issue-4446.rs10
-rw-r--r--src/test/run-pass/issue-4448.rs10
-rw-r--r--src/test/run-pass/issue-7784.rs2
-rw-r--r--src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs2
-rw-r--r--src/test/run-pass/issue-8827.rs19
-rw-r--r--src/test/run-pass/issue-9396.rs11
-rw-r--r--src/test/run-pass/ivec-tag.rs5
-rw-r--r--src/test/run-pass/logging-only-prints-once.rs8
-rw-r--r--src/test/run-pass/macro-with-braces-in-expr-position.rs4
-rw-r--r--src/test/run-pass/match-with-ret-arm.rs1
-rw-r--r--src/test/run-pass/method-self-arg-trait.rs2
-rw-r--r--src/test/run-pass/numeric-method-autoexport.rs3
-rw-r--r--src/test/run-pass/out-of-stack-new-thread-no-split.rs8
-rw-r--r--src/test/run-pass/overloaded-autoderef-count.rs8
-rw-r--r--src/test/run-pass/overloaded-autoderef-indexing.rs8
-rw-r--r--src/test/run-pass/overloaded-autoderef-order.rs13
-rw-r--r--src/test/run-pass/overloaded-autoderef-vtable.rs6
-rw-r--r--src/test/run-pass/overloaded-autoderef.rs3
-rw-r--r--src/test/run-pass/overloaded-calls-param-vtables.rs5
-rw-r--r--src/test/run-pass/overloaded-deref-count.rs8
-rw-r--r--src/test/run-pass/overloaded-index-autoderef.rs2
-rw-r--r--src/test/run-pass/overloaded-index-in-field.rs2
-rw-r--r--src/test/run-pass/overloaded-index.rs2
-rw-r--r--src/test/run-pass/rename-directory.rs1
-rw-r--r--src/test/run-pass/running-with-no-runtime.rs11
-rw-r--r--src/test/run-pass/rust-log-filter.rs17
-rw-r--r--src/test/run-pass/self-in-mut-slot-default-method.rs2
-rw-r--r--src/test/run-pass/send-resource.rs7
-rw-r--r--src/test/run-pass/send-type-inference.rs2
-rw-r--r--src/test/run-pass/send_str_hashmap.rs2
-rw-r--r--src/test/run-pass/send_str_treemap.rs3
-rw-r--r--src/test/run-pass/sendable-class.rs2
-rw-r--r--src/test/run-pass/spawn-types.rs1
-rw-r--r--src/test/run-pass/supertrait-default-generics.rs2
-rw-r--r--src/test/run-pass/task-comm-0.rs14
-rw-r--r--src/test/run-pass/task-comm-10.rs14
-rw-r--r--src/test/run-pass/task-comm-11.rs2
-rw-r--r--src/test/run-pass/task-comm-13.rs2
-rw-r--r--src/test/run-pass/task-comm-14.rs2
-rw-r--r--src/test/run-pass/task-comm-15.rs2
-rw-r--r--src/test/run-pass/task-comm-16.rs33
-rw-r--r--src/test/run-pass/task-comm-3.rs5
-rw-r--r--src/test/run-pass/task-comm-4.rs34
-rw-r--r--src/test/run-pass/task-comm-5.rs6
-rw-r--r--src/test/run-pass/task-comm-6.rs18
-rw-r--r--src/test/run-pass/task-comm-7.rs12
-rw-r--r--src/test/run-pass/task-comm-9.rs5
-rw-r--r--src/test/run-pass/task-comm-chan-nil.rs6
-rw-r--r--src/test/run-pass/task-spawn-move-and-copy.rs5
-rw-r--r--src/test/run-pass/task-stderr.rs1
-rw-r--r--src/test/run-pass/tcp-accept-stress.rs10
-rw-r--r--src/test/run-pass/tcp-connect-timeouts.rs7
-rw-r--r--src/test/run-pass/tcp-stress.rs19
-rw-r--r--src/test/run-pass/tempfile.rs9
-rw-r--r--src/test/run-pass/trait-bounds-in-arc.rs2
-rw-r--r--src/test/run-pass/trait-impl.rs11
-rw-r--r--src/test/run-pass/trait-inheritance-overloading.rs1
-rw-r--r--src/test/run-pass/trivial-message.rs2
-rw-r--r--src/test/run-pass/unboxed-closures-call-sugar-object.rs25
-rw-r--r--src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-bound.rs2
-rw-r--r--src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-object-type.rs2
-rw-r--r--src/test/run-pass/unboxed-closures-infer-argument-types-with-bound-regions-from-expected-bound.rs2
-rw-r--r--src/test/run-pass/unique-send-2.rs5
-rw-r--r--src/test/run-pass/unique-send.rs6
-rw-r--r--src/test/run-pass/unwind-resource.rs6
-rw-r--r--src/test/run-pass/variadic-ffi.rs3
-rw-r--r--src/test/run-pass/vector-sort-panic-safe.rs20
-rw-r--r--src/test/run-pass/wait-forked-but-failed-child.rs2
488 files changed, 6697 insertions, 4791 deletions
diff --git a/.travis.yml b/.travis.yml
index 26199005298..03e38f4e0c1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,7 @@
 # RVM/bundler/ruby and whatnot. Right now 'rust' as a language actually
 # downloads a rust/cargo snapshot, which we don't really want for building rust.
 language: c
+sudo: false
 
 # The test suite is in general way too stressful for travis, especially in
 # terms of time limit and reliability. In the past we've tried to scale things
diff --git a/mk/dist.mk b/mk/dist.mk
index a8b331c6cc2..6986746a117 100644
--- a/mk/dist.mk
+++ b/mk/dist.mk
@@ -212,7 +212,7 @@ distcheck-osx: dist-osx
 # Unix binary installer tarballs
 ######################################################################
 
-NON_INSTALLED_PREFIXES=COPYRIGHT,LICENSE-APACHE,LICENSE-MIT,README.md,doc
+NON_INSTALLED_PREFIXES=COPYRIGHT,LICENSE-APACHE,LICENSE-MIT,README.md,version
 
 define DEF_INSTALLER
 
@@ -236,6 +236,8 @@ dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs
 	$$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-APACHE $$(PREPARE_DEST_DIR)/share/doc/rust
 	$$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-MIT $$(PREPARE_DEST_DIR)/share/doc/rust
 	$$(Q)$$(PREPARE_MAN_CMD) $$(S)README.md $$(PREPARE_DEST_DIR)/share/doc/rust
+# This tiny morsel of metadata is used by rust-packaging
+	$$(Q)echo "$(CFG_VERSION)" > $$(PREPARE_DEST_DIR)/version
 
 dist/$$(PKG_NAME)-$(1).tar.gz: dist-install-dir-$(1)
 	@$(call E, build: $$@)
diff --git a/mk/install.mk b/mk/install.mk
index f36ca4db7ca..a8dfdffb59d 100644
--- a/mk/install.mk
+++ b/mk/install.mk
@@ -28,7 +28,11 @@ endif
 # Remove tmp files because it's a decent amount of disk space
 	$(Q)rm -R tmp/dist
 
+ifeq ($(CFG_DISABLE_DOCS),)
+prepare_install: dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz dist/$(DOC_PKG_NAME)-$(CFG_BUILD).tar.gz | tmp/empty_dir
+else
 prepare_install: dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz | tmp/empty_dir
+endif
 
 uninstall:
 ifeq (root user, $(USER) $(patsubst %,user,$(SUDO_USER)))
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index bdbfbfd7c89..ad1264828cb 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -22,8 +22,8 @@ extern crate regex;
 use std::os;
 use std::io;
 use std::io::fs;
-use std::str::FromStr;
-use std::thunk::{Thunk};
+use std::str::{FromStr, from_str};
+use std::thunk::Thunk;
 use getopts::{optopt, optflag, reqopt};
 use common::Config;
 use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Codegen};
diff --git a/src/doc/guide-ffi.md b/src/doc/guide-ffi.md
index 3a87271ede7..b8808eaf57d 100644
--- a/src/doc/guide-ffi.md
+++ b/src/doc/guide-ffi.md
@@ -450,6 +450,8 @@ them.
 
 ~~~no_run
 extern crate libc;
+
+use std::c_str::ToCStr;
 use std::ptr;
 
 #[link(name = "readline")]
diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md
index 29c98e22ee9..8eb13187e58 100644
--- a/src/doc/guide-tasks.md
+++ b/src/doc/guide-tasks.md
@@ -206,6 +206,7 @@ getting the result later.
 The basic example below illustrates this.
 
 ```{rust,ignore}
+# #![allow(deprecated)]
 use std::sync::Future;
 
 # fn main() {
@@ -233,6 +234,7 @@ Here is another example showing how futures allow you to background
 computations. The workload will be distributed on the available cores.
 
 ```{rust,ignore}
+# #![allow(deprecated)]
 # use std::num::Float;
 # use std::sync::Future;
 fn partial_sum(start: uint) -> f64 {
diff --git a/src/doc/guide.md b/src/doc/guide.md
index f4ec787a794..55465651cfb 100644
--- a/src/doc/guide.md
+++ b/src/doc/guide.md
@@ -26,7 +26,7 @@ in the `$`s, they just indicate the start of each command):
 curl -L https://static.rust-lang.org/rustup.sh | sudo sh
 ```
 
-If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`, 
+If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`,
 please keep reading and see our disclaimer below. And feel free to use a two-step version of the installation and examine our installation script:
 
 ```bash
@@ -1106,13 +1106,21 @@ enum Ordering {
 ```
 
 An `Ordering` can only be _one_ of `Less`, `Equal`, or `Greater` at any given
-time. Here's an example:
+time.
+
+Because `Ordering` is provided by the standard library, we can use the `use`
+keyword to use it in our code. We'll learn more about `use` later, but it's
+used to bring names into scope.
+
+Here's an example of how to use `Ordering`:
 
 ```{rust}
+use std::cmp::Ordering;
+
 fn cmp(a: int, b: int) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 
 fn main() {
@@ -1121,28 +1129,35 @@ fn main() {
 
     let ordering = cmp(x, y); // ordering: Ordering
 
-    if ordering == Less {
+    if ordering == Ordering::Less {
         println!("less");
-    } else if ordering == Greater {
+    } else if ordering == Ordering::Greater {
         println!("greater");
-    } else if ordering == Equal {
+    } else if ordering == Ordering::Equal {
         println!("equal");
     }
 }
 ```
 
-`cmp` is a function that compares two things, and returns an `Ordering`. We
-return either `Less`, `Greater`, or `Equal`, depending on if the two values
-are greater, less, or equal.
+There's a symbol here we haven't seen before: the double colon (`::`).
+This is used to indicate a namesapce. In this case, `Ordering` lives in
+the `cmp` submodule of the `std` module. We'll talk more about modules
+later in the guide. For now, all you need to know is that you can `use`
+things from the standard library if you need them.
 
-The `ordering` variable has the type `Ordering`, and so contains one of the
-three values. We can then do a bunch of `if`/`else` comparisons to check
-which one it is.
+Okay, let's talk about the actual code in the example. `cmp` is a function that
+compares two things, and returns an `Ordering`. We return either
+`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on if
+the two values are greater, less, or equal. Note that each variant of the
+`enum` is namespaced under the `enum` itself: it's `Ordering::Greater` not
+`Greater`.
 
-However, repeated `if`/`else` comparisons get quite tedious. Rust has a feature
-that not only makes them nicer to read, but also makes sure that you never
-miss a case. Before we get to that, though, let's talk about another kind of
-enum: one with values.
+The `ordering` variable has the type `Ordering`, and so contains one of the
+three values. We can then do a bunch of `if`/`else` comparisons to check which
+one it is. However, repeated `if`/`else` comparisons get quite tedious. Rust
+has a feature that not only makes them nicer to read, but also makes sure that
+you never miss a case. Before we get to that, though, let's talk about another
+kind of enum: one with values.
 
 This enum has two variants, one of which has a value:
 
@@ -1175,18 +1190,19 @@ enum StringResult {
     ErrorReason(String),
 }
 ```
-Where a `StringResult` is either a `StringOK`, with the result of a computation, or an
-`ErrorReason` with a `String` explaining what caused the computation to fail. These kinds of
-`enum`s are actually very useful and are even part of the standard library.
+Where a `StringResult` is either a `StringResult::StringOK`, with the result of
+a computation, or an `StringResult::ErrorReason` with a `String` explaining
+what caused the computation to fail. These kinds of `enum`s are actually very
+useful and are even part of the standard library.
 
-Enum variants are namespaced under the enum names. For example, here is an example of using
-our `StringResult`:
+Here is an example of using our `StringResult`:
 
 ```rust
-# enum StringResult {
-#     StringOK(String),
-#     ErrorReason(String),
-# }
+enum StringResult {
+    StringOK(String),
+    ErrorReason(String),
+}
+
 fn respond(greeting: &str) -> StringResult {
     if greeting == "Hello" {
         StringResult::StringOK("Good morning!".to_string())
@@ -1196,10 +1212,7 @@ fn respond(greeting: &str) -> StringResult {
 }
 ```
 
-Notice that we need both the enum name and the variant name: `StringResult::StringOK`, but
-we didn't need to with `Ordering` – we just said `Greater` rather than `Ordering::Greater`.
-There's a reason: the Rust prelude imports the variants of `Ordering` as well as the enum
-itself. We can use the `use` keyword to do something similar with `StringResult`:
+That's a lot of typing! We can use the `use` keyword to make it shorter:
 
 ```rust
 use StringResult::StringOK;
@@ -1221,12 +1234,11 @@ fn respond(greeting: &str) -> StringResult {
 }
 ```
 
-We'll learn more about `use` later, but it's used to bring names into scope. `use` declarations
-must come before anything else, which looks a little strange in this example, since we `use`
-the variants before we define them. Anyway, in the body of `respond`, we can just say `StringOK`
-now, rather than the full `StringResult::StringOK`. Importing variants can be convenient, but can
-also cause name conflicts, so do this with caution. It's considered good style to rarely import
-variants for this reason.
+`use` declarations must come before anything else, which looks a little strange in this example,
+since we `use` the variants before we define them. Anyway, in the body of `respond`, we can just
+say `StringOK` now, rather than the full `StringResult::StringOK`. Importing variants can be
+convenient, but can also cause name conflicts, so do this with caution. It's considered good style
+to rarely import variants for this reason.
 
 As you can see, `enum`s with values are quite a powerful tool for data representation,
 and can be even more useful when they're generic across types. Before we get to generics,
@@ -1280,10 +1292,12 @@ for every possible value of `x`, and so our program will compile successfully.
 section on enums?
 
 ```{rust}
+use std::cmp::Ordering;
+
 fn cmp(a: int, b: int) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 
 fn main() {
@@ -1292,11 +1306,11 @@ fn main() {
 
     let ordering = cmp(x, y);
 
-    if ordering == Less {
+    if ordering == Ordering::Less {
         println!("less");
-    } else if ordering == Greater {
+    } else if ordering == Ordering::Greater {
         println!("greater");
-    } else if ordering == Equal {
+    } else if ordering == Ordering::Equal {
         println!("equal");
     }
 }
@@ -1305,10 +1319,12 @@ fn main() {
 We can re-write this as a `match`:
 
 ```{rust}
+use std::cmp::Ordering;
+
 fn cmp(a: int, b: int) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 
 fn main() {
@@ -1316,9 +1332,9 @@ fn main() {
     let y = 10i;
 
     match cmp(x, y) {
-        Less    => println!("less"),
-        Greater => println!("greater"),
-        Equal   => println!("equal"),
+        Ordering::Less    => println!("less"),
+        Ordering::Greater => println!("greater"),
+        Ordering::Equal   => println!("equal"),
     }
 }
 ```
@@ -1365,10 +1381,12 @@ side of a `let` binding or directly where an expression is used. We could
 also implement the previous line like this:
 
 ```{rust}
+use std::cmp::Ordering;
+
 fn cmp(a: int, b: int) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 
 fn main() {
@@ -1376,9 +1394,9 @@ fn main() {
     let y = 10i;
 
     println!("{}", match cmp(x, y) {
-        Less    => "less",
-        Greater => "greater",
-        Equal   => "equal",
+        Ordering::Less    => "less",
+        Ordering::Greater => "greater",
+        Ordering::Equal   => "equal",
     });
 }
 ```
@@ -2139,6 +2157,7 @@ guess to the secret number:
 ```{rust,ignore}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2157,16 +2176,16 @@ fn main() {
     println!("You guessed: {}", input);
 
     match cmp(input, secret_number) {
-        Less    => println!("Too small!"),
-        Greater => println!("Too big!"),
-        Equal   => println!("You win!"),
+        Ordering::Less    => println!("Too small!"),
+        Ordering::Greater => println!("Too big!"),
+        Ordering::Equal   => println!("You win!"),
     }
 }
 
 fn cmp(a: int, b: int) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2193,6 +2212,7 @@ we wrote the `cmp` function! Let's change it to take `uint`s:
 ```{rust,ignore}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2211,16 +2231,16 @@ fn main() {
     println!("You guessed: {}", input);
 
     match cmp(input, secret_number) {
-        Less    => println!("Too small!"),
-        Greater => println!("Too big!"),
-        Equal   => println!("You win!"),
+        Ordering::Less    => println!("Too small!"),
+        Ordering::Greater => println!("Too big!"),
+        Ordering::Equal   => println!("You win!"),
     }
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2290,6 +2310,7 @@ Anyway, with us now converting our input to a number, our code looks like this:
 ```{rust,ignore}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2308,16 +2329,16 @@ fn main() {
     println!("You guessed: {}", input_num);
 
     match cmp(input_num, secret_number) {
-        Less    => println!("Too small!"),
-        Greater => println!("Too big!"),
-        Equal   => println!("You win!"),
+        Ordering::Less    => println!("Too small!"),
+        Ordering::Greater => println!("Too big!"),
+        Ordering::Equal   => println!("You win!"),
     }
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2339,6 +2360,7 @@ to do that. Try this code:
 ```{rust,no_run}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2366,16 +2388,16 @@ fn main() {
     println!("You guessed: {}", num);
 
     match cmp(num, secret_number) {
-        Less    => println!("Too small!"),
-        Greater => println!("Too big!"),
-        Equal   => println!("You win!"),
+        Ordering::Less    => println!("Too small!"),
+        Ordering::Greater => println!("Too big!"),
+        Ordering::Equal   => println!("You win!"),
     }
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2405,6 +2427,7 @@ code looks like this:
 ```{rust,no_run}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2432,16 +2455,16 @@ fn main() {
     println!("You guessed: {}", num);
 
     match cmp(num, secret_number) {
-        Less    => println!("Too small!"),
-        Greater => println!("Too big!"),
-        Equal   => println!("You win!"),
+        Ordering::Less    => println!("Too small!"),
+        Ordering::Greater => println!("Too big!"),
+        Ordering::Equal   => println!("You win!"),
     }
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2478,6 +2501,7 @@ Let's add that in:
 ```{rust,no_run}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2507,17 +2531,17 @@ fn main() {
         println!("You guessed: {}", num);
 
         match cmp(num, secret_number) {
-            Less    => println!("Too small!"),
-            Greater => println!("Too big!"),
-            Equal   => println!("You win!"),
+            Ordering::Less    => println!("Too small!"),
+            Ordering::Greater => println!("Too big!"),
+            Ordering::Equal   => println!("You win!"),
         }
     }
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2553,6 +2577,7 @@ suboptimal to say the least. First, let's actually quit when you win the game:
 ```{rust,no_run}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2582,9 +2607,9 @@ fn main() {
         println!("You guessed: {}", num);
 
         match cmp(num, secret_number) {
-            Less    => println!("Too small!"),
-            Greater => println!("Too big!"),
-            Equal   => {
+            Ordering::Less    => println!("Too small!"),
+            Ordering::Greater => println!("Too big!"),
+            Ordering::Equal   => {
                 println!("You win!");
                 return;
             },
@@ -2593,9 +2618,9 @@ fn main() {
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2608,6 +2633,7 @@ we don't want to quit, we just want to ignore it. Change that `return` to
 ```{rust,no_run}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2637,9 +2663,9 @@ fn main() {
         println!("You guessed: {}", num);
 
         match cmp(num, secret_number) {
-            Less    => println!("Too small!"),
-            Greater => println!("Too big!"),
-            Equal   => {
+            Ordering::Less    => println!("Too small!"),
+            Ordering::Greater => println!("Too big!"),
+            Ordering::Equal   => {
                 println!("You win!");
                 return;
             },
@@ -2648,9 +2674,9 @@ fn main() {
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -2686,6 +2712,7 @@ It was good for testing, but it kind of ruins the game. Here's our final source:
 ```{rust,no_run}
 use std::io;
 use std::rand;
+use std::cmp::Ordering;
 
 fn main() {
     println!("Guess the number!");
@@ -2713,9 +2740,9 @@ fn main() {
         println!("You guessed: {}", num);
 
         match cmp(num, secret_number) {
-            Less    => println!("Too small!"),
-            Greater => println!("Too big!"),
-            Equal   => {
+            Ordering::Less    => println!("Too small!"),
+            Ordering::Greater => println!("Too big!"),
+            Ordering::Equal   => {
                 println!("You win!");
                 return;
             },
@@ -2724,9 +2751,9 @@ fn main() {
 }
 
 fn cmp(a: uint, b: uint) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
+    if a < b { Ordering::Less }
+    else if a > b { Ordering::Greater }
+    else { Ordering::Equal }
 }
 ```
 
@@ -4154,7 +4181,7 @@ We've made a struct that represents a circle. We then write an `impl` block,
 and inside it, define a method, `area`. Methods take a  special first
 parameter, `&self`. There are three variants: `self`, `&self`, and `&mut self`.
 You can think of this first parameter as being the `x` in `x.foo()`. The three
-variants correspond to the three kinds of thing `x` could be: `self` if it's
+variants correspond to the three kinds of things `x` could be: `self` if it's
 just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
 a mutable reference. We should default to using `&self`, as it's the most
 common.
@@ -4742,13 +4769,13 @@ enum OptionalFloat64 {
 }
 ```
 
-This is really unfortunate. Luckily, Rust has a feature that gives us a better
-way: generics. Generics are called **parametric polymorphism** in type theory,
-which means that they are types or functions that have multiple forms ("poly"
-is multiple, "morph" is form) over a given parameter ("parametric").
+Such repetition is unfortunate. Luckily, Rust has a feature that gives us a
+better way: **generics**. Generics are called **parametric polymorphism** in
+type theory, which means that they are types or functions that have multiple
+forms over a given parameter ("parametric").
 
-Anyway, enough with type theory declarations, let's check out the generic form
-of `OptionalInt`. It is actually provided by Rust itself, and looks like this:
+Let's see how generics help us escape `OptionalInt`. `Option` is already
+provided in Rust's standard library and looks like this:
 
 ```rust
 enum Option<T> {
@@ -4757,25 +4784,27 @@ enum Option<T> {
 }
 ```
 
-The `<T>` part, which you've seen a few times before, indicates that this is
-a generic data type. Inside the declaration of our enum, wherever we see a `T`,
-we substitute that type for the same type used in the generic. Here's an
-example of using `Option<T>`, with some extra type annotations:
+The `<T>` part, which you've seen a few times before, indicates that this is a
+generic data type. `T` is called a **type parameter**. When we create instances
+of `Option`, we need to provide a concrete type in place of the type
+parameter. For example, if we wanted something like our `OptionalInt`, we would
+need to instantiate an `Option<int>`. Inside the declaration of our enum,
+wherever we see a `T`, we replace it with the type specified (or inferred by the
+the compiler).
 
 ```{rust}
 let x: Option<int> = Some(5i);
 ```
 
-In the type declaration, we say `Option<int>`. Note how similar this looks to
-`Option<T>`. So, in this particular `Option`, `T` has the value of `int`. On
-the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5i`.
-Since that's an `int`, the two sides match, and Rust is happy. If they didn't
-match, we'd get an error:
+In this particular `Option`, `T` has the value of `int`. On the right-hand side
+of the binding, we do make a `Some(T)`, where `T` is `5i`.  Since that's an
+`int`, the two sides match, and Rust is happy. If they didn't match, we'd get an
+error:
 
 ```{rust,ignore}
 let x: Option<f64> = Some(5i);
-// error: mismatched types: expected `core::option::Option<f64>`
-// but found `core::option::Option<int>` (expected f64 but found int)
+// error: mismatched types: expected `core::option::Option<f64>`,
+// found `core::option::Option<int>` (expected f64, found int)
 ```
 
 That doesn't mean we can't make `Option<T>`s that hold an `f64`! They just have to
@@ -4786,8 +4815,6 @@ let x: Option<int> = Some(5i);
 let y: Option<f64> = Some(5.0f64);
 ```
 
-This is just fine. One definition, multiple uses.
-
 Generics don't have to only be generic over one type. Consider Rust's built-in
 `Result<T, E>` type:
 
@@ -4808,20 +4835,20 @@ enum Result<H, N> {
 }
 ```
 
-if we wanted to. Convention says that the first generic parameter should be
-`T`, for 'type,' and that we use `E` for 'error'. Rust doesn't care, however.
+Convention says that the first generic parameter should be `T`, for "type," and
+that we use `E` for "error."
 
-The `Result<T, E>` type is intended to
-be used to return the result of a computation, and to have the ability to
-return an error if it didn't work out. Here's an example:
+The `Result<T, E>` type is intended to be used to return the result of a
+computation and to have the ability to return an error if it didn't work
+out. Here's an example:
 
 ```{rust}
 let x: Result<f64, String> = Ok(2.3f64);
 let y: Result<f64, String> = Err("There was an error.".to_string());
 ```
 
-This particular Result will return an `f64` if there's a success, and a
-`String` if there's a failure. Let's write a function that uses `Result<T, E>`:
+This particular `Result` will return an `f64` upon success and a `String` if
+there's a failure. Let's write a function that uses `Result<T, E>`:
 
 ```{rust}
 fn inverse(x: f64) -> Result<f64, String> {
@@ -4831,17 +4858,18 @@ fn inverse(x: f64) -> Result<f64, String> {
 }
 ```
 
-We don't want to take the inverse of zero, so we check to make sure that we
-weren't passed zero. If we were, then we return an `Err`, with a message. If
-it's okay, we return an `Ok`, with the answer.
+We want to indicate that `inverse(0.0f64)` is undefined or is an erroneous usage
+of the function, so we check to make sure that we weren't passed zero. If we
+were, we return an `Err` with a message. If it's okay, we return an `Ok` with
+the answer.
 
 Why does this matter? Well, remember how `match` does exhaustive matches?
 Here's how this function gets used:
 
 ```{rust}
 # fn inverse(x: f64) -> Result<f64, String> {
-#     if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
-#     Ok(1.0f64 / x)
+# if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
+# Ok(1.0f64 / x)
 # }
 let x = inverse(25.0f64);
 
@@ -4862,8 +4890,8 @@ println!("{}", x + 2.0f64); // error: binary operation `+` cannot be applied
 ```
 
 This function is great, but there's one other problem: it only works for 64 bit
-floating point values. What if we wanted to handle 32 bit floating point as
-well? We'd have to write this:
+floating point values. If we wanted to handle 32 bit floating point values we'd
+have to write this:
 
 ```{rust}
 fn inverse32(x: f32) -> Result<f32, String> {
@@ -4873,9 +4901,9 @@ fn inverse32(x: f32) -> Result<f32, String> {
 }
 ```
 
-Bummer. What we need is a **generic function**. Luckily, we can write one!
-However, it won't _quite_ work yet. Before we get into that, let's talk syntax.
-A generic version of `inverse` would look something like this:
+What we need is a **generic function**. We can do that with Rust! However, it
+won't _quite_ work yet. We need to talk about syntax. A first attempt at a
+generic version of `inverse` might look something like this:
 
 ```{rust,ignore}
 fn inverse<T>(x: T) -> Result<T, String> {
@@ -4885,24 +4913,34 @@ fn inverse<T>(x: T) -> Result<T, String> {
 }
 ```
 
-Just like how we had `Option<T>`, we use a similar syntax for `inverse<T>`.
-We can then use `T` inside the rest of the signature: `x` has type `T`, and half
-of the `Result` has type `T`. However, if we try to compile that example, we'll get
-an error:
+Just like how we had `Option<T>`, we use a similar syntax for `inverse<T>`.  We
+can then use `T` inside the rest of the signature: `x` has type `T`, and half of
+the `Result` has type `T`. However, if we try to compile that example, we'll get
+some errors:
 
 ```text
 error: binary operation `==` cannot be applied to type `T`
+     if x == 0.0 { return Err("x cannot be zero!".to_string()); }
+                ^~~~~~~~
+error: mismatched types: expected `_`, found `T` (expected floating-point variable, found type parameter)
+     Ok(1.0 / x)
+              ^
+error: mismatched types: expected `core::result::Result<T, collections::string::String>`, found `core::result::Result<_, _>` (expected type parameter, found floating-point variable)
+     Ok(1.0 / x)
+     ^~~~~~~~~~~
 ```
 
-Because `T` can be _any_ type, it may be a type that doesn't implement `==`,
-and therefore, the first line would be wrong. What do we do?
+The problem is that `T` is unconstrained: it can be _any_ type. It could be a
+`String`, and the expression `1.0 / x` has no meaning if `x` is a `String`. It
+may be a type that doesn't implement `==`, and the first line would be
+wrong. What do we do?
 
-To fix this example, we need to learn about another Rust feature: traits.
+To fix this example, we need to learn about another Rust feature: **traits**.
 
 # Traits
 
-Do you remember the `impl` keyword, used to call a function with method
-syntax?
+Our discussion of **traits** begins with the `impl` keyword. We used it before
+to specify methods.
 
 ```{rust}
 struct Circle {
@@ -4918,8 +4956,8 @@ impl Circle {
 }
 ```
 
-Traits are similar, except that we define a trait with just the method
-signature, then implement the trait for that struct. Like this:
+We define a trait in terms of its methods. We then `impl` a trait `for` a type
+(or many types).
 
 ```{rust}
 struct Circle {
@@ -4939,19 +4977,18 @@ impl HasArea for Circle {
 }
 ```
 
-As you can see, the `trait` block looks very similar to the `impl` block,
-but we don't define a body, just a type signature. When we `impl` a trait,
-we use `impl Trait for Item`, rather than just `impl Item`.
+The `trait` block defines only type signatures. When we `impl` a trait, we use
+`impl Trait for Item`, rather than just `impl Item`.
 
-So what's the big deal? Remember the error we were getting with our generic
-`inverse` function?
+The first of the three errors we got with our generic `inverse` function was
+this:
 
 ```text
 error: binary operation `==` cannot be applied to type `T`
 ```
 
-We can use traits to constrain our generics. Consider this function, which
-does not compile, and gives us a similar error:
+We can use traits to constrain generic type parameters. Consider this function,
+which does not compile, and gives us a similar error:
 
 ```{rust,ignore}
 fn print_area<T>(shape: T) {
@@ -4966,8 +5003,9 @@ error: type `T` does not implement any method in scope named `area`
 ```
 
 Because `T` can be any type, we can't be sure that it implements the `area`
-method. But we can add a **trait constraint** to our generic `T`, ensuring
-that it does:
+method. But we can add a **trait constraint** to our generic `T`, ensuring that
+we can only compile the function if it's called with types which `impl` the
+`HasArea` trait:
 
 ```{rust}
 # trait HasArea {
@@ -4978,9 +5016,9 @@ fn print_area<T: HasArea>(shape: T) {
 }
 ```
 
-The syntax `<T: HasArea>` means `any type that implements the HasArea trait`.
-Because traits define function type signatures, we can be sure that any type
-which implements `HasArea` will have an `.area()` method.
+The syntax `<T: HasArea>` means "any type that implements the HasArea trait."
+Because traits define method signatures, we can be sure that any type which
+implements `HasArea` will have an `area` method.
 
 Here's an extended example of how this works:
 
@@ -5078,55 +5116,22 @@ impl HasArea for int {
 It is considered poor style to implement methods on such primitive types, even
 though it is possible.
 
-This may seem like the Wild West, but there are two other restrictions around
-implementing traits that prevent this from getting out of hand. First, traits
-must be `use`d in any scope where you wish to use the trait's method. So for
-example, this does not work:
-
-```{rust,ignore}
-mod shapes {
-    use std::f64::consts;
-
-    trait HasArea {
-        fn area(&self) -> f64;
-    }
-
-    struct Circle {
-        x: f64,
-        y: f64,
-        radius: f64,
-    }
-
-    impl HasArea for Circle {
-        fn area(&self) -> f64 {
-            consts::PI * (self.radius * self.radius)
-        }
-    }
-}
-
-fn main() {
-    let c = shapes::Circle {
-        x: 0.0f64,
-        y: 0.0f64,
-        radius: 1.0f64,
-    };
+## Scoped Method Resolution and Orphan `impl`s
 
-    println!("{}", c.area());
-}
-```
+There are two restrictions for implementing traits that prevent this from
+getting out of hand.
 
-Now that we've moved the structs and traits into their own module, we get an
-error:
+1. **Scope-based Method Resolution**: Traits must be `use`d in any scope where
+   you wish to use the trait's methods
+2. **No Orphan `impl`s**: Either the trait or the type you're writing the `impl`
+   for must be inside your crate.
 
-```text
-error: type `shapes::Circle` does not implement any method in scope named `area`
-```
-
-If we add a `use` line right above `main` and make the right things public,
-everything is fine:
+If we organize our crate differently by using modules, we'll need to ensure both
+of the conditions are satisfied. Don't worry, you can lean on the compiler since
+it won't let you get away with violating them.
 
 ```{rust}
-use shapes::HasArea;
+use shapes::HasArea; // satisfies #1
 
 mod shapes {
     use std::f64::consts;
@@ -5148,8 +5153,8 @@ mod shapes {
     }
 }
 
-
 fn main() {
+    // use shapes::HasArea; // This would satisfy #1, too
     let c = shapes::Circle {
         x: 0.0f64,
         y: 0.0f64,
@@ -5160,18 +5165,25 @@ fn main() {
 }
 ```
 
-This means that even if someone does something bad like add methods to `int`,
-it won't affect you, unless you `use` that trait.
+Requiring us to `use` traits whose methods we want means that even if someone
+does something bad like add methods to `int`, it won't affect us, unless you
+`use` that trait.
 
-There's one more restriction on implementing traits. Either the trait or the
-type you're writing the `impl` for must be inside your crate. So, we could
-implement the `HasArea` type for `int`, because `HasArea` is in our crate.  But
-if we tried to implement `Float`, a trait provided by Rust, for `int`, we could
-not, because both the trait and the type aren't in our crate.
+The second condition allows us to `impl` built-in `trait`s for types we define,
+or allows us to `impl` our own `trait`s for built-in types, but restricts us
+from mixing and matching third party or built-in `impl`s with third party or
+built-in types.
 
-One last thing about traits: generic functions with a trait bound use
-**monomorphization** ("mono": one, "morph": form), so they are statically
-dispatched. What's that mean? Well, let's take a look at `print_area` again:
+We could `impl` the `HasArea` trait for `int`, because `HasArea` is in our
+crate. But if we tried to implement `Float`, a standard library `trait`, for
+`int`, we could not, because neither the `trait` nor the `type` are in our
+crate.
+
+## Monomorphization
+
+One last thing about generics and traits: the compiler performs
+**monomorphization** on generic functions so they are statically dispatched. To
+see what that means, let's take a look at `print_area` again:
 
 ```{rust,ignore}
 fn print_area<T: HasArea>(shape: T) {
@@ -5188,10 +5200,11 @@ fn main() {
 }
 ```
 
-When we use this trait with `Circle` and `Square`, Rust ends up generating
-two different functions with the concrete type, and replacing the call sites with
-calls to the concrete implementations. In other words, you get something like
-this:
+Because we have called `print_area` with two different types in place of its
+type paramater `T`, Rust will generate two versions of the function with the
+appropriate concrete types, replacing the call sites with calls to the concrete
+implementations. In other words, the compiler will actually compile something
+more like this:
 
 ```{rust,ignore}
 fn __print_area_circle(shape: Circle) {
@@ -5212,12 +5225,14 @@ fn main() {
 }
 ```
 
-The names don't actually change to this, it's just for illustration. But
-as you can see, there's no overhead of deciding which version to call here,
-hence 'statically dispatched'. The downside is that we have two copies of
-the same function, so our binary is a little bit larger.
+These names are for illustration; the compiler will generate its own cryptic
+names for internal uses. The point is that there is no runtime overhead of
+deciding which version to call. The function to be called is determined
+statically, at compile time. Thus, generic functions are **statically
+dispatched**. The downside is that we have two similar functions, so our binary
+is larger.
 
-# Threads 
+# Threads
 
 Concurrency and parallelism are topics that are of increasing interest to a
 broad subsection of software developers. Modern computers are often multi-core,
@@ -5312,6 +5327,7 @@ example, if you wish to compute some value in the background, `Future` is
 a useful thing to use:
 
 ```{rust}
+# #![allow(deprecated)]
 use std::sync::Future;
 
 let mut delayed_value = Future::spawn(move || {
diff --git a/src/doc/reference.md b/src/doc/reference.md
index f3ad19bbd2a..a8abb595034 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1480,9 +1480,9 @@ data are being stored, or single-address and mutability properties are required.
 ```
 use std::sync::atomic;
 
-// Note that INIT_ATOMIC_UINT is a *const*, but it may be used to initialize a
+// Note that ATOMIC_UINT_INIT is a *const*, but it may be used to initialize a
 // static. This static can be modified, so it is not placed in read-only memory.
-static COUNTER: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+static COUNTER: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
 
 // This table is a candidate to be placed in read-only memory.
 static TABLE: &'static [uint] = &[1, 2, 3, /* ... */];
@@ -2561,6 +2561,9 @@ The currently implemented features of the reference compiler are:
                 if the system linker is not used then specifying custom flags
                 doesn't have much meaning.
 
+* `link_llvm_intrinsics` – Allows linking to LLVM intrinsics via
+                           `#[link_name="llvm.*"]`.
+
 * `linkage` - Allows use of the `linkage` attribute, which is not portable.
 
 * `log_syntax` - Allows use of the `log_syntax` macro attribute, which is a
@@ -4149,11 +4152,11 @@ Unwinding the stack of a thread is done by the thread itself, on its own control
 stack. If a value with a destructor is freed during unwinding, the code for the
 destructor is run, also on the thread's control stack. Running the destructor
 code causes a temporary transition to a *running* state, and allows the
-destructor code to cause any subsequent state transitions. The original thread 
+destructor code to cause any subsequent state transitions. The original thread
 of unwinding and panicking thereby may suspend temporarily, and may involve
 (recursive) unwinding of the stack of a failed destructor. Nonetheless, the
 outermost unwinding activity will continue until the stack is unwound and the
-thread transitions to the *dead* state. There is no way to "recover" from thread 
+thread transitions to the *dead* state. There is no way to "recover" from thread
 panics. Once a thread has temporarily suspended its unwinding in the *panicking*
 state, a panic occurring from within this destructor results in *hard* panic.
 A hard panic currently results in the process aborting.
diff --git a/src/etc/licenseck.py b/src/etc/licenseck.py
index 7669df36b04..9ac0acc38a7 100644
--- a/src/etc/licenseck.py
+++ b/src/etc/licenseck.py
@@ -38,8 +38,8 @@ exceptions = [
     "rt/isaac/randport.cpp", # public domain
     "rt/isaac/rand.h", # public domain
     "rt/isaac/standard.h", # public domain
-    "libstd/comm/mpsc_queue.rs", # BSD
-    "libstd/comm/spsc_queue.rs", # BSD
+    "libstd/sync/mpsc/mpsc_queue.rs", # BSD
+    "libstd/sync/mpsc/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/liballoc/arc.rs b/src/liballoc/arc.rs
index 820a3838978..59106aa9777 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -247,7 +247,9 @@ impl<T> BorrowFrom<Arc<T>> for T {
 }
 
 #[experimental = "Deref is experimental."]
-impl<T> Deref<T> for Arc<T> {
+impl<T> Deref for Arc<T> {
+    type Target = T;
+
     #[inline]
     fn deref(&self) -> &T {
         &self.inner().data
@@ -593,7 +595,7 @@ impl<T: Default + Sync + Send> Default for Arc<T> {
 #[allow(experimental)]
 mod tests {
     use std::clone::Clone;
-    use std::comm::channel;
+    use std::sync::mpsc::channel;
     use std::mem::drop;
     use std::ops::Drop;
     use std::option::Option;
@@ -630,11 +632,11 @@ mod tests {
         let (tx, rx) = channel();
 
         task::spawn(move || {
-            let arc_v: Arc<Vec<int>> = rx.recv();
+            let arc_v: Arc<Vec<int>> = rx.recv().unwrap();
             assert_eq!((*arc_v)[3], 4);
         });
 
-        tx.send(arc_v.clone());
+        tx.send(arc_v.clone()).unwrap();
 
         assert_eq!((*arc_v)[2], 3);
         assert_eq!((*arc_v)[4], 5);
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 74f0599e486..e836b08459b 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -10,6 +10,8 @@
 
 //! A unique pointer type.
 
+#![stable]
+
 use core::any::{Any, AnyRefExt};
 use core::clone::Clone;
 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
@@ -44,7 +46,7 @@ pub static HEAP: () = ();
 
 /// A type that represents a uniquely-owned value.
 #[lang = "owned_box"]
-#[unstable = "custom allocators will add an additional type parameter (with default)"]
+#[stable]
 pub struct Box<T>(Unique<T>);
 
 #[stable]
@@ -111,20 +113,20 @@ impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
     }
 }
 
-
 /// Extension methods for an owning `Any` trait object.
 #[unstable = "post-DST and coherence changes, this will not be a trait but \
               rather a direct `impl` on `Box<Any>`"]
 pub trait BoxAny {
     /// Returns the boxed value if it is of type `T`, or
     /// `Err(Self)` if it isn't.
-    #[unstable = "naming conventions around accessing innards may change"]
+    #[stable]
     fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
 }
 
-#[stable]
 impl BoxAny for Box<Any> {
     #[inline]
+    #[unstable = "method may be renamed with respect to other downcasting \
+                  methods"]
     fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
         if self.is::<T>() {
             unsafe {
@@ -147,17 +149,19 @@ impl<Sized? T: fmt::Show> fmt::Show for Box<T> {
     }
 }
 
-impl fmt::Show for Box<Any+'static> {
+impl fmt::Show for Box<Any> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.pad("Box<Any>")
     }
 }
 
-impl<Sized? T> Deref<T> for Box<T> {
+impl<Sized? T> Deref for Box<T> {
+    type Target = T;
+
     fn deref(&self) -> &T { &**self }
 }
 
-impl<Sized? T> DerefMut<T> for Box<T> {
+impl<Sized? T> DerefMut for Box<T> {
     fn deref_mut(&mut self) -> &mut T { &mut **self }
 }
 
@@ -210,7 +214,7 @@ mod test {
 
     #[test]
     fn deref() {
-        fn homura<T: Deref<i32>>(_: T) { }
+        fn homura<T: Deref<Target=i32>>(_: T) { }
         homura(box 765i32);
     }
 }
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 61b5d43d1cb..aab513ddeb7 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -64,7 +64,9 @@
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
 #![no_std]
-#![feature(lang_items, phase, unsafe_destructor, default_type_params)]
+#![allow(unknown_features)]
+#![feature(lang_items, phase, unsafe_destructor, default_type_params, old_orphan_check)]
+#![feature(associated_types)]
 
 #[phase(plugin, link)]
 extern crate core;
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index bd250938836..c57231fc434 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -355,7 +355,9 @@ impl<T> BorrowFrom<Rc<T>> for T {
 }
 
 #[experimental = "Deref is experimental."]
-impl<T> Deref<T> for Rc<T> {
+impl<T> Deref for Rc<T> {
+    type Target = T;
+
     #[inline(always)]
     fn deref(&self) -> &T {
         &self.inner().value
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index 64e10e69a2e..f748c8ad1eb 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -26,6 +26,7 @@
 //! [dir_graph]: http://en.wikipedia.org/wiki/Directed_graph
 //!
 //! ```
+//! use std::cmp::Ordering;
 //! use std::collections::BinaryHeap;
 //! use std::uint;
 //!
@@ -151,6 +152,7 @@
 use core::prelude::*;
 
 use core::default::Default;
+use core::iter::FromIterator;
 use core::mem::{zeroed, replace, swap};
 use core::ptr;
 
diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index d8dfc02c97a..6ea624df034 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -82,17 +82,20 @@
 
 use core::prelude::*;
 
+use core::cmp::Ordering;
 use core::cmp;
 use core::default::Default;
 use core::fmt;
-use core::iter::{Cloned, Chain, Enumerate, Repeat, Skip, Take, repeat};
-use core::iter;
+use core::hash;
+use core::iter::RandomAccessIterator;
+use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat, Cloned};
+use core::iter::{mod, FromIterator};
 use core::num::Int;
+use core::ops::Index;
 use core::slice;
 use core::{u8, u32, uint};
 use bitv_set; //so meta
 
-use core::hash;
 use Vec;
 
 type Blocks<'a> = Cloned<slice::Iter<'a, u32>>;
@@ -2507,7 +2510,7 @@ mod tests {
 
 #[cfg(test)]
 mod bitv_bench {
-    use std::prelude::*;
+    use std::prelude::v1::*;
     use std::rand;
     use std::rand::Rng;
     use std::u32;
@@ -3002,7 +3005,7 @@ mod bitv_set_test {
 
 #[cfg(test)]
 mod bitv_set_bench {
-    use std::prelude::*;
+    use std::prelude::v1::*;
     use std::rand;
     use std::rand::Rng;
     use std::u32;
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 87b40aa1cee..da98c19e888 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -19,21 +19,23 @@ pub use self::Entry::*;
 
 use core::prelude::*;
 
-use self::StackOp::*;
-use super::node::{mod, Node, Found, GoDown};
-use super::node::{Traversal, MutTraversal, MoveTraversal};
-use super::node::TraversalItem::{mod, Elem, Edge};
-use super::node::ForceResult::{Leaf, Internal};
 use core::borrow::BorrowFrom;
-use std::hash::{Writer, Hash};
+use core::cmp::Ordering;
 use core::default::Default;
-use core::{iter, fmt, mem};
 use core::fmt::Show;
-use core::iter::Map;
+use core::hash::{Writer, Hash};
+use core::iter::{Map, FromIterator};
+use core::ops::{Index, IndexMut};
+use core::{iter, fmt, mem};
 
 use ring_buf::RingBuf;
 
 use self::Continuation::{Continue, Finished};
+use self::StackOp::*;
+use super::node::ForceResult::{Leaf, Internal};
+use super::node::TraversalItem::{mod, Elem, Edge};
+use super::node::{Traversal, MutTraversal, MoveTraversal};
+use super::node::{mod, Node, Found, GoDown};
 
 // FIXME(conventions): implement bounded iterators
 
@@ -501,6 +503,7 @@ mod stack {
     use core::prelude::*;
     use core::kinds::marker;
     use core::mem;
+    use core::ops::{Deref, DerefMut};
     use super::BTreeMap;
     use super::super::node::{mod, Node, Fit, Split, Internal, Leaf};
     use super::super::node::handle;
@@ -515,13 +518,15 @@ mod stack {
         marker: marker::InvariantLifetime<'id>
     }
 
-    impl<'id, T> Deref<T> for IdRef<'id, T> {
+    impl<'id, T> Deref for IdRef<'id, T> {
+        type Target = T;
+
         fn deref(&self) -> &T {
             &*self.inner
         }
     }
 
-    impl<'id, T> DerefMut<T> for IdRef<'id, T> {
+    impl<'id, T> DerefMut for IdRef<'id, T> {
         fn deref_mut(&mut self) -> &mut T {
             &mut *self.inner
         }
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index 3907f28092a..3dddcae11ce 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -18,10 +18,12 @@ pub use self::TraversalItem::*;
 
 use core::prelude::*;
 
-use core::{slice, mem, ptr, cmp, num, raw};
-use core::iter::Zip;
 use core::borrow::BorrowFrom;
+use core::cmp::Ordering::{Greater, Less, Equal};
+use core::iter::Zip;
+use core::ops::{Deref, DerefMut};
 use core::ptr::Unique;
+use core::{slice, mem, ptr, cmp, num, raw};
 use alloc::heap;
 
 /// Represents the result of an Insertion: either the item fit, or the node had to split
@@ -455,7 +457,9 @@ impl<K: Clone, V: Clone> Clone for Node<K, V> {
 ///     flag: &'a Cell<bool>,
 /// }
 ///
-/// impl<'a> Deref<Node<uint, uint>> for Nasty<'a> {
+/// impl<'a> Deref for Nasty<'a> {
+///     type Target = Node<uint, uint>;
+///
 ///     fn deref(&self) -> &Node<uint, uint> {
 ///         if self.flag.get() {
 ///             &*self.second
@@ -511,7 +515,7 @@ impl<K: Ord, V> Node<K, V> {
     /// Searches for the given key in the node. If it finds an exact match,
     /// `Found` will be yielded with the matching index. If it doesn't find an exact match,
     /// `GoDown` will be yielded with the index of the subtree the key must lie in.
-    pub fn search<Sized? Q, NodeRef: Deref<Node<K, V>>>(node: NodeRef, key: &Q)
+    pub fn search<Sized? Q, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &Q)
                   -> SearchResult<NodeRef> where Q: BorrowFrom<K> + Ord {
         // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
         // For the B configured as of this writing (B = 6), binary search was *significantly*
@@ -588,7 +592,7 @@ impl <K, V> Node<K, V> {
     }
 }
 
-impl<K, V, NodeRef: Deref<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> {
+impl<K, V, NodeRef: Deref<Target=Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> {
     /// Returns a reference to the node that contains the pointed-to edge or key/value pair. This
     /// is very different from `edge` and `edge_mut` because those return children of the node
     /// returned by `node`.
@@ -597,7 +601,9 @@ impl<K, V, NodeRef: Deref<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, Nod
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>, Type, NodeType> Handle<NodeRef, Type, NodeType> {
+impl<K, V, NodeRef, Type, NodeType> Handle<NodeRef, Type, NodeType> where
+    NodeRef: Deref<Target=Node<K, V>> + DerefMut,
+{
     /// Converts a handle into one that stores the same information using a raw pointer. This can
     /// be useful in conjunction with `from_raw` when the type system is insufficient for
     /// determining the lifetimes of the nodes.
@@ -653,7 +659,7 @@ impl<'a, K: 'a, V: 'a> Handle<&'a mut Node<K, V>, handle::Edge, handle::Internal
     }
 }
 
-impl<K, V, NodeRef: Deref<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> {
+impl<K, V, NodeRef: Deref<Target=Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> {
     // This doesn't exist because there are no uses for it,
     // but is fine to add, analagous to edge_mut.
     //
@@ -667,7 +673,7 @@ pub enum ForceResult<NodeRef, Type> {
     Internal(Handle<NodeRef, Type, handle::Internal>)
 }
 
-impl<K, V, NodeRef: Deref<Node<K, V>>, Type> Handle<NodeRef, Type, handle::LeafOrInternal> {
+impl<K, V, NodeRef: Deref<Target=Node<K, V>>, Type> Handle<NodeRef, Type, handle::LeafOrInternal> {
     /// Figure out whether this handle is pointing to something in a leaf node or to something in
     /// an internal node, clarifying the type according to the result.
     pub fn force(self) -> ForceResult<NodeRef, Type> {
@@ -684,8 +690,9 @@ impl<K, V, NodeRef: Deref<Node<K, V>>, Type> Handle<NodeRef, Type, handle::LeafO
         }
     }
 }
-
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Leaf> {
+impl<K, V, NodeRef> Handle<NodeRef, handle::Edge, handle::Leaf> where
+    NodeRef: Deref<Target=Node<K, V>> + DerefMut,
+{
     /// Tries to insert this key-value pair at the given index in this leaf node
     /// If the node is full, we have to split it.
     ///
@@ -717,7 +724,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::Internal> {
+impl<K, V, NodeRef> Handle<NodeRef, handle::Edge, handle::Internal> where
+    NodeRef: Deref<Target=Node<K, V>> + DerefMut,
+{
     /// Returns a mutable reference to the edge pointed-to by this handle. This should not be
     /// confused with `node`, which references the parent node of what is returned here.
     pub fn edge_mut(&mut self) -> &mut Node<K, V> {
@@ -800,7 +809,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::Edge, handle::
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::Edge, NodeType> {
+impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
+    NodeRef: Deref<Target=Node<K, V>> + DerefMut,
+{
     /// Gets the handle pointing to the key/value pair just to the left of the pointed-to edge.
     /// This is unsafe because the handle might point to the first edge in the node, which has no
     /// pair to its left.
@@ -862,7 +873,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, handle::KV, NodeType
     }
 }
 
-impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV,
+impl<'a, K: 'a, V: 'a, NodeRef: Deref<Target=Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV,
                                                                          NodeType> {
     // These are fine to include, but are currently unneeded.
     //
@@ -881,8 +892,9 @@ impl<'a, K: 'a, V: 'a, NodeRef: Deref<Node<K, V>> + 'a, NodeType> Handle<NodeRef
     // }
 }
 
-impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a, NodeType> Handle<NodeRef, handle::KV,
-                                                                            NodeType> {
+impl<'a, K: 'a, V: 'a, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
+    NodeRef: 'a + Deref<Target=Node<K, V>> + DerefMut,
+{
     /// Returns a mutable reference to the key pointed-to by this handle. This doesn't return a
     /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the
     /// handle.
@@ -898,7 +910,9 @@ impl<'a, K: 'a, V: 'a, NodeRef: DerefMut<Node<K, V>> + 'a, NodeType> Handle<Node
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::KV, NodeType> {
+impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
+    NodeRef: Deref<Target=Node<K, V>> + DerefMut,
+{
     /// Gets the handle pointing to the edge immediately to the left of the key/value pair pointed
     /// to by this handle.
     pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
@@ -918,7 +932,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>, NodeType> Handle<NodeRef, handle::KV,
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Leaf> {
+impl<K, V, NodeRef> Handle<NodeRef, handle::KV, handle::Leaf> where
+    NodeRef: Deref<Target=Node<K, V>> + DerefMut,
+{
     /// Removes the key/value pair at the handle's location.
     ///
     /// # Panics (in debug build)
@@ -929,7 +945,9 @@ impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Le
     }
 }
 
-impl<K, V, NodeRef: DerefMut<Node<K, V>>> Handle<NodeRef, handle::KV, handle::Internal> {
+impl<K, V, NodeRef> Handle<NodeRef, handle::KV, handle::Internal> where
+    NodeRef: Deref<Target=Node<K, V>> + DerefMut
+{
     /// Steal! Stealing is roughly analogous to a binary tree rotation.
     /// In this case, we're "rotating" right.
     unsafe fn steal_rightward(&mut self) {
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index f3f6727f1c0..3e8988530e6 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -13,13 +13,16 @@
 
 use core::prelude::*;
 
-use btree_map::{BTreeMap, Keys};
-use std::hash::Hash;
 use core::borrow::BorrowFrom;
+use core::cmp::Ordering::{mod, Less, Greater, Equal};
 use core::default::Default;
-use core::fmt;
-use core::iter::{Peekable, Map};
 use core::fmt::Show;
+use core::fmt;
+use core::hash::Hash;
+use core::iter::{Peekable, Map, FromIterator};
+use core::ops::{BitOr, BitAnd, BitXor, Sub};
+
+use btree_map::{BTreeMap, Keys};
 
 // FIXME(conventions): implement bounded iterators
 
diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs
index 8b7b7176b80..68acbfcb3c3 100644
--- a/src/libcollections/dlist.rs
+++ b/src/libcollections/dlist.rs
@@ -22,12 +22,13 @@
 use core::prelude::*;
 
 use alloc::boxed::Box;
+use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
-use core::iter;
+use core::hash::{Writer, Hash};
+use core::iter::{mod, FromIterator};
 use core::mem;
 use core::ptr;
-use std::hash::{Writer, Hash};
 
 /// A doubly-linked list.
 #[stable]
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index b484fc41ff6..ea3d8659f54 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -16,6 +16,8 @@
 use core::prelude::*;
 use core::fmt;
 use core::num::Int;
+use core::iter::FromIterator;
+use core::ops::{Sub, BitOr, BitAnd, BitXor};
 
 // FIXME(contentions): implement union family of methods? (general design may be wrong here)
 
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index cbd8d4955b2..fac9ab8107a 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -25,6 +25,8 @@
 #![feature(macro_rules, default_type_params, phase, globs)]
 #![feature(unsafe_destructor, slicing_syntax)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
+#![feature(associated_types)]
 #![no_std]
 
 #[phase(plugin, link)] extern crate core;
@@ -120,7 +122,6 @@ mod prelude {
     pub use core::result::Result::{Ok, Err};
 
     // in core and collections (may differ).
-    pub use slice::{PartialEqSliceExt, OrdSliceExt};
     pub use slice::{AsSlice, SliceExt};
     pub use str::{from_str, Str, StrExt};
 
@@ -129,7 +130,7 @@ mod prelude {
     pub use unicode::char::UnicodeChar;
 
     // from collections.
-    pub use slice::{CloneSliceExt, SliceConcatExt};
+    pub use slice::SliceConcatExt;
     pub use str::IntoMaybeOwned;
     pub use string::{String, ToString};
     pub use vec::Vec;
diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs
index 12148947a19..e4c9e51a845 100644
--- a/src/libcollections/ring_buf.rs
+++ b/src/libcollections/ring_buf.rs
@@ -14,14 +14,16 @@
 
 use core::prelude::*;
 
+use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
-use core::iter;
-use core::raw::Slice as RawSlice;
-use core::ptr;
+use core::iter::{mod, FromIterator, RandomAccessIterator};
 use core::kinds::marker;
 use core::mem;
 use core::num::{Int, UnsignedInt};
+use core::ops::{Index, IndexMut};
+use core::ptr;
+use core::raw::Slice as RawSlice;
 
 use std::hash::{Writer, Hash};
 use std::cmp;
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 61111d96bd0..1c1b48f8cef 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -89,22 +89,26 @@
 
 use alloc::boxed::Box;
 use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
-use core::cmp;
-use core::iter::{range_step, MultiplicativeIterator};
+use core::clone::Clone;
+use core::cmp::Ordering::{mod, Greater, Less};
+use core::cmp::{mod, Ord, PartialEq};
+use core::iter::{Iterator, IteratorExt, IteratorCloneExt};
+use core::iter::{range, range_step, MultiplicativeIterator};
 use core::kinds::Sized;
 use core::mem::size_of;
 use core::mem;
-use core::ops::{FnMut,SliceMut};
-use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
-use core::prelude::{Ord, Ordering, PtrExt, Some, range, IteratorCloneExt, Result};
+use core::ops::{FnMut, SliceMut};
+use core::option::Option::{mod, Some, None};
+use core::ptr::PtrExt;
 use core::ptr;
+use core::result::Result;
 use core::slice as core_slice;
 use self::Direction::*;
 
 use vec::Vec;
 
 pub use core::slice::{Chunks, AsSlice, Windows};
-pub use core::slice::{Iter, IterMut, PartialEqSliceExt};
+pub use core::slice::{Iter, IterMut};
 pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
 pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
 pub use core::slice::{bytes, mut_ref_slice, ref_slice};
@@ -122,7 +126,9 @@ pub type MutItems<'a, T:'a> = IterMut<'a, T>;
 
 /// Allocating extension methods for slices.
 #[unstable = "needs associated types, may merge with other traits"]
-pub trait SliceExt<T> for Sized? {
+pub trait SliceExt for Sized? {
+    type Item;
+
     /// Sorts the slice, in place, using `compare` to compare
     /// elements.
     ///
@@ -141,7 +147,7 @@ pub trait SliceExt<T> for Sized? {
     /// assert!(v == [5, 4, 3, 2, 1]);
     /// ```
     #[stable]
-    fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering;
+    fn sort_by<F>(&mut self, compare: F) where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
 
     /// Consumes `src` and moves as many elements as it can into `self`
     /// from the range [start,end).
@@ -165,7 +171,7 @@ pub trait SliceExt<T> for Sized? {
     /// assert!(a == [6i, 7, 8, 4, 5]);
     /// ```
     #[experimental = "uncertain about this API approach"]
-    fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint;
+    fn move_from(&mut self, src: Vec<Self::Item>, start: uint, end: uint) -> uint;
 
     /// Returns a subslice spanning the interval [`start`, `end`).
     ///
@@ -174,7 +180,7 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Slicing with `start` equal to `end` yields an empty slice.
     #[experimental = "will be replaced by slice syntax"]
-    fn slice(&self, start: uint, end: uint) -> &[T];
+    fn slice(&self, start: uint, end: uint) -> &[Self::Item];
 
     /// Returns a subslice from `start` to the end of the slice.
     ///
@@ -182,7 +188,7 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Slicing from `self.len()` yields an empty slice.
     #[experimental = "will be replaced by slice syntax"]
-    fn slice_from(&self, start: uint) -> &[T];
+    fn slice_from(&self, start: uint) -> &[Self::Item];
 
     /// Returns a subslice from the start of the slice to `end`.
     ///
@@ -190,7 +196,7 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Slicing to `0` yields an empty slice.
     #[experimental = "will be replaced by slice syntax"]
-    fn slice_to(&self, end: uint) -> &[T];
+    fn slice_to(&self, end: uint) -> &[Self::Item];
 
     /// Divides one slice into two at an index.
     ///
@@ -200,32 +206,32 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Panics if `mid > len`.
     #[stable]
-    fn split_at(&self, mid: uint) -> (&[T], &[T]);
+    fn split_at(&self, mid: uint) -> (&[Self::Item], &[Self::Item]);
 
     /// Returns an iterator over the slice
     #[stable]
-    fn iter(&self) -> Iter<T>;
+    fn iter(&self) -> Iter<Self::Item>;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`.  The matched element is not contained in the subslices.
     #[stable]
-    fn split<F>(&self, pred: F) -> Split<T, F>
-                where F: FnMut(&T) -> bool;
+    fn split<F>(&self, pred: F) -> Split<Self::Item, F>
+                where F: FnMut(&Self::Item) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to splitting at most `n` times.  The matched element is
     /// not contained in the subslices.
     #[stable]
-    fn splitn<F>(&self, n: uint, pred: F) -> SplitN<T, F>
-                 where F: FnMut(&T) -> bool;
+    fn splitn<F>(&self, n: uint, pred: F) -> SplitN<Self::Item, F>
+                 where F: FnMut(&Self::Item) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred` limited to splitting at most `n` times. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
     #[stable]
-    fn rsplitn<F>(&self, n: uint, pred: F) -> RSplitN<T, F>
-                  where F: FnMut(&T) -> bool;
+    fn rsplitn<F>(&self, n: uint, pred: F) -> RSplitN<Self::Item, F>
+                  where F: FnMut(&Self::Item) -> bool;
 
     /// Returns an iterator over all contiguous windows of length
     /// `size`. The windows overlap. If the slice is shorter than
@@ -247,7 +253,7 @@ pub trait SliceExt<T> for Sized? {
     /// }
     /// ```
     #[stable]
-    fn windows(&self, size: uint) -> Windows<T>;
+    fn windows(&self, size: uint) -> Windows<Self::Item>;
 
     /// Returns an iterator over `size` elements of the slice at a
     /// time. The chunks do not overlap. If `size` does not divide the
@@ -270,41 +276,41 @@ pub trait SliceExt<T> for Sized? {
     /// }
     /// ```
     #[stable]
-    fn chunks(&self, size: uint) -> Chunks<T>;
+    fn chunks(&self, size: uint) -> Chunks<Self::Item>;
 
     /// Returns the element of a slice at the given index, or `None` if the
     /// index is out of bounds.
     #[stable]
-    fn get(&self, index: uint) -> Option<&T>;
+    fn get(&self, index: uint) -> Option<&Self::Item>;
 
     /// Returns the first element of a slice, or `None` if it is empty.
     #[stable]
-    fn first(&self) -> Option<&T>;
+    fn first(&self) -> Option<&Self::Item>;
 
     /// Deprecated: renamed to `first`.
     #[deprecated = "renamed to `first`"]
-    fn head(&self) -> Option<&T> { self.first() }
+    fn head(&self) -> Option<&Self::Item> { self.first() }
 
     /// Returns all but the first element of a slice.
     #[experimental = "likely to be renamed"]
-    fn tail(&self) -> &[T];
+    fn tail(&self) -> &[Self::Item];
 
     /// Returns all but the last element of a slice.
     #[experimental = "likely to be renamed"]
-    fn init(&self) -> &[T];
+    fn init(&self) -> &[Self::Item];
 
     /// Returns the last element of a slice, or `None` if it is empty.
     #[stable]
-    fn last(&self) -> Option<&T>;
+    fn last(&self) -> Option<&Self::Item>;
 
     /// Returns a pointer to the element at the given index, without doing
     /// bounds checking.
     #[stable]
-    unsafe fn get_unchecked(&self, index: uint) -> &T;
+    unsafe fn get_unchecked(&self, index: uint) -> &Self::Item;
 
     /// Deprecated: renamed to `get_unchecked`.
     #[deprecated = "renamed to get_unchecked"]
-    unsafe fn unsafe_get(&self, index: uint) -> &T {
+    unsafe fn unsafe_get(&self, index: uint) -> &Self::Item {
         self.get_unchecked(index)
     }
 
@@ -316,7 +322,7 @@ pub trait SliceExt<T> for Sized? {
     /// Modifying the slice may cause its buffer to be reallocated, which
     /// would also make any pointers to it invalid.
     #[stable]
-    fn as_ptr(&self) -> *const T;
+    fn as_ptr(&self) -> *const Self::Item;
 
     /// Binary search a sorted slice with a comparator function.
     ///
@@ -352,7 +358,7 @@ pub trait SliceExt<T> for Sized? {
     /// ```
     #[stable]
     fn binary_search_by<F>(&self, f: F) -> Result<uint, uint> where
-        F: FnMut(&T) -> Ordering;
+        F: FnMut(&Self::Item) -> Ordering;
 
     /// Return the number of elements in the slice
     ///
@@ -379,12 +385,12 @@ pub trait SliceExt<T> for Sized? {
     /// Returns a mutable reference to the element at the given index,
     /// or `None` if the index is out of bounds
     #[stable]
-    fn get_mut(&mut self, index: uint) -> Option<&mut T>;
+    fn get_mut(&mut self, index: uint) -> Option<&mut Self::Item>;
 
     /// Work with `self` as a mut slice.
     /// Primarily intended for getting a &mut [T] from a [T; N].
     #[stable]
-    fn as_mut_slice(&mut self) -> &mut [T];
+    fn as_mut_slice(&mut self) -> &mut [Self::Item];
 
     /// Returns a mutable subslice spanning the interval [`start`, `end`).
     ///
@@ -393,7 +399,7 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Slicing with `start` equal to `end` yields an empty slice.
     #[experimental = "will be replaced by slice syntax"]
-    fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T];
+    fn slice_mut(&mut self, start: uint, end: uint) -> &mut [Self::Item];
 
     /// Returns a mutable subslice from `start` to the end of the slice.
     ///
@@ -401,7 +407,7 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Slicing from `self.len()` yields an empty slice.
     #[experimental = "will be replaced by slice syntax"]
-    fn slice_from_mut(&mut self, start: uint) -> &mut [T];
+    fn slice_from_mut(&mut self, start: uint) -> &mut [Self::Item];
 
     /// Returns a mutable subslice from the start of the slice to `end`.
     ///
@@ -409,54 +415,54 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Slicing to `0` yields an empty slice.
     #[experimental = "will be replaced by slice syntax"]
-    fn slice_to_mut(&mut self, end: uint) -> &mut [T];
+    fn slice_to_mut(&mut self, end: uint) -> &mut [Self::Item];
 
     /// Returns an iterator that allows modifying each value
     #[stable]
-    fn iter_mut(&mut self) -> IterMut<T>;
+    fn iter_mut(&mut self) -> IterMut<Self::Item>;
 
     /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
     #[stable]
-    fn first_mut(&mut self) -> Option<&mut T>;
+    fn first_mut(&mut self) -> Option<&mut Self::Item>;
 
     /// Depreated: renamed to `first_mut`.
     #[deprecated = "renamed to first_mut"]
-    fn head_mut(&mut self) -> Option<&mut T> {
+    fn head_mut(&mut self) -> Option<&mut Self::Item> {
         self.first_mut()
     }
 
     /// Returns all but the first element of a mutable slice
     #[experimental = "likely to be renamed or removed"]
-    fn tail_mut(&mut self) -> &mut [T];
+    fn tail_mut(&mut self) -> &mut [Self::Item];
 
     /// Returns all but the last element of a mutable slice
     #[experimental = "likely to be renamed or removed"]
-    fn init_mut(&mut self) -> &mut [T];
+    fn init_mut(&mut self) -> &mut [Self::Item];
 
     /// Returns a mutable pointer to the last item in the slice.
     #[stable]
-    fn last_mut(&mut self) -> Option<&mut T>;
+    fn last_mut(&mut self) -> Option<&mut Self::Item>;
 
     /// Returns an iterator over mutable subslices separated by elements that
     /// match `pred`.  The matched element is not contained in the subslices.
     #[stable]
-    fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
-                    where F: FnMut(&T) -> bool;
+    fn split_mut<F>(&mut self, pred: F) -> SplitMut<Self::Item, F>
+                    where F: FnMut(&Self::Item) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to splitting at most `n` times.  The matched element is
     /// not contained in the subslices.
     #[stable]
-    fn splitn_mut<F>(&mut self, n: uint, pred: F) -> SplitNMut<T, F>
-                     where F: FnMut(&T) -> bool;
+    fn splitn_mut<F>(&mut self, n: uint, pred: F) -> SplitNMut<Self::Item, F>
+                     where F: FnMut(&Self::Item) -> bool;
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred` limited to splitting at most `n` times. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
     #[stable]
-    fn rsplitn_mut<F>(&mut self,  n: uint, pred: F) -> RSplitNMut<T, F>
-                      where F: FnMut(&T) -> bool;
+    fn rsplitn_mut<F>(&mut self,  n: uint, pred: F) -> RSplitNMut<Self::Item, F>
+                      where F: FnMut(&Self::Item) -> bool;
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable and do not overlap. If `chunk_size` does
@@ -467,7 +473,7 @@ pub trait SliceExt<T> for Sized? {
     ///
     /// Panics if `chunk_size` is 0.
     #[stable]
-    fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<T>;
+    fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<Self::Item>;
 
     /// Swaps two elements in a slice.
     ///
@@ -525,7 +531,7 @@ pub trait SliceExt<T> for Sized? {
     /// }
     /// ```
     #[stable]
-    fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]);
+    fn split_at_mut(&mut self, mid: uint) -> (&mut [Self::Item], &mut [Self::Item]);
 
     /// Reverse the order of elements in a slice, in place.
     ///
@@ -541,11 +547,11 @@ pub trait SliceExt<T> for Sized? {
 
     /// Returns an unsafe mutable pointer to the element in index
     #[stable]
-    unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T;
+    unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut Self::Item;
 
     /// Deprecated: renamed to `get_unchecked_mut`.
     #[deprecated = "renamed to get_unchecked_mut"]
-    unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T {
+    unsafe fn unchecked_mut(&mut self, index: uint) -> &mut Self::Item {
         self.get_unchecked_mut(index)
     }
 
@@ -558,11 +564,179 @@ pub trait SliceExt<T> for Sized? {
     /// would also make any pointers to it invalid.
     #[inline]
     #[stable]
-    fn as_mut_ptr(&mut self) -> *mut T;
+    fn as_mut_ptr(&mut self) -> *mut Self::Item;
+
+    /// Copies `self` into a new `Vec`.
+    #[stable]
+    fn to_vec(&self) -> Vec<Self::Item> where Self::Item: Clone;
+
+    /// Deprecated: use `iter().cloned().partition(f)` instead.
+    #[deprecated = "use iter().cloned().partition(f) instead"]
+    fn partitioned<F>(&self, f: F) -> (Vec<Self::Item>, Vec<Self::Item>) where
+        Self::Item: Clone,
+        F: FnMut(&Self::Item) -> bool;
+
+    /// Creates an iterator that yields every possible permutation of the
+    /// vector in succession.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let v = [1i, 2, 3];
+    /// let mut perms = v.permutations();
+    ///
+    /// for p in perms {
+    ///   println!("{}", p);
+    /// }
+    /// ```
+    ///
+    /// Iterating through permutations one by one.
+    ///
+    /// ```rust
+    /// let v = [1i, 2, 3];
+    /// let mut perms = v.permutations();
+    ///
+    /// assert_eq!(Some(vec![1i, 2, 3]), perms.next());
+    /// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
+    /// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
+    /// ```
+    #[unstable]
+    fn permutations(&self) -> Permutations<Self::Item> where Self::Item: Clone;
+
+    /// Copies as many elements from `src` as it can into `self` (the
+    /// shorter of `self.len()` and `src.len()`). Returns the number
+    /// of elements copied.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut dst = [0i, 0, 0];
+    /// let src = [1i, 2];
+    ///
+    /// assert!(dst.clone_from_slice(&src) == 2);
+    /// assert!(dst == [1, 2, 0]);
+    ///
+    /// let src2 = [3i, 4, 5, 6];
+    /// assert!(dst.clone_from_slice(&src2) == 3);
+    /// assert!(dst == [3i, 4, 5]);
+    /// ```
+    #[experimental]
+    fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone;
+
+    /// Sorts the slice, in place.
+    ///
+    /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let mut v = [-5i, 4, 1, -3, 2];
+    ///
+    /// v.sort();
+    /// assert!(v == [-5i, -3, 1, 2, 4]);
+    /// ```
+    #[stable]
+    fn sort(&mut self) where Self::Item: Ord;
+
+    /// Binary search a sorted slice for a given element.
+    ///
+    /// If the value is found then `Ok` is returned, containing the
+    /// index of the matching element; if the value is not found then
+    /// `Err` is returned, containing the index where a matching
+    /// element could be inserted while maintaining sorted order.
+    ///
+    /// # Example
+    ///
+    /// Looks up a series of four elements. The first is found, with a
+    /// uniquely determined position; the second and third are not
+    /// found; the fourth could match any position in `[1,4]`.
+    ///
+    /// ```rust
+    /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+    /// let s = s.as_slice();
+    ///
+    /// assert_eq!(s.binary_search(&13),  Ok(9));
+    /// assert_eq!(s.binary_search(&4),   Err(7));
+    /// assert_eq!(s.binary_search(&100), Err(13));
+    /// let r = s.binary_search(&1);
+    /// assert!(match r { Ok(1...4) => true, _ => false, });
+    /// ```
+    #[stable]
+    fn binary_search(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord;
+
+    /// Deprecated: use `binary_search` instead.
+    #[deprecated = "use binary_search instead"]
+    fn binary_search_elem(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord {
+        self.binary_search(x)
+    }
+
+    /// Mutates the slice to the next lexicographic permutation.
+    ///
+    /// Returns `true` if successful and `false` if the slice is at the
+    /// last-ordered permutation.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v: &mut [_] = &mut [0i, 1, 2];
+    /// v.next_permutation();
+    /// let b: &mut [_] = &mut [0i, 2, 1];
+    /// assert!(v == b);
+    /// v.next_permutation();
+    /// let b: &mut [_] = &mut [1i, 0, 2];
+    /// assert!(v == b);
+    /// ```
+    #[unstable = "uncertain if this merits inclusion in std"]
+    fn next_permutation(&mut self) -> bool where Self::Item: Ord;
+
+    /// Mutates the slice to the previous lexicographic permutation.
+    ///
+    /// Returns `true` if successful and `false` if the slice is at the
+    /// first-ordered permutation.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v: &mut [_] = &mut [1i, 0, 2];
+    /// v.prev_permutation();
+    /// let b: &mut [_] = &mut [0i, 2, 1];
+    /// assert!(v == b);
+    /// v.prev_permutation();
+    /// let b: &mut [_] = &mut [0i, 1, 2];
+    /// assert!(v == b);
+    /// ```
+    #[unstable = "uncertain if this merits inclusion in std"]
+    fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
+
+    /// Find the first index containing a matching value.
+    #[experimental]
+    fn position_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
+
+    /// Find the last index containing a matching value.
+    #[experimental]
+    fn rposition_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
+
+    /// Return true if the slice contains an element with the given value.
+    #[stable]
+    fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
+
+    /// Returns true if `needle` is a prefix of the slice.
+    #[stable]
+    fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+
+    /// Returns true if `needle` is a suffix of the slice.
+    #[stable]
+    fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+
+    /// Convert `self` into a vector without clones or allocation.
+    #[experimental]
+    fn into_vec(self: Box<Self>) -> Vec<Self::Item>;
 }
 
 #[unstable = "trait is unstable"]
-impl<T> SliceExt<T> for [T] {
+impl<T> SliceExt for [T] {
+    type Item = T;
+
     #[inline]
     fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering {
         merge_sort(self, compare)
@@ -777,96 +951,10 @@ impl<T> SliceExt<T> for [T] {
     fn as_mut_ptr(&mut self) -> *mut T {
         core_slice::SliceExt::as_mut_ptr(self)
     }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Extension traits for slices over specifc kinds of data
-////////////////////////////////////////////////////////////////////////////////
-
-/// Extension methods for boxed slices.
-#[experimental = "likely to merge into SliceExt if it survives"]
-pub trait BoxedSliceExt<T> {
-    /// Convert `self` into a vector without clones or allocation.
-    #[experimental]
-    fn into_vec(self) -> Vec<T>;
-}
-
-#[experimental = "trait is experimental"]
-impl<T> BoxedSliceExt<T> for Box<[T]> {
-    fn into_vec(mut self) -> Vec<T> {
-        unsafe {
-            let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
-            mem::forget(self);
-            xs
-        }
-    }
-}
-
-/// Allocating extension methods for slices containing `Clone` elements.
-#[unstable = "likely to be merged into SliceExt"]
-pub trait CloneSliceExt<T> for Sized? {
-    /// Copies `self` into a new `Vec`.
-    #[stable]
-    fn to_vec(&self) -> Vec<T>;
-
-    /// Deprecated: use `iter().cloned().partition(f)` instead.
-    #[deprecated = "use iter().cloned().partition(f) instead"]
-    fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool;
-
-    /// Creates an iterator that yields every possible permutation of the
-    /// vector in succession.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// let v = [1i, 2, 3];
-    /// let mut perms = v.permutations();
-    ///
-    /// for p in perms {
-    ///   println!("{}", p);
-    /// }
-    /// ```
-    ///
-    /// Iterating through permutations one by one.
-    ///
-    /// ```rust
-    /// let v = [1i, 2, 3];
-    /// let mut perms = v.permutations();
-    ///
-    /// assert_eq!(Some(vec![1i, 2, 3]), perms.next());
-    /// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
-    /// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
-    /// ```
-    #[unstable]
-    fn permutations(&self) -> Permutations<T>;
-
-    /// Copies as many elements from `src` as it can into `self` (the
-    /// shorter of `self.len()` and `src.len()`). Returns the number
-    /// of elements copied.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut dst = [0i, 0, 0];
-    /// let src = [1i, 2];
-    ///
-    /// assert!(dst.clone_from_slice(&src) == 2);
-    /// assert!(dst == [1, 2, 0]);
-    ///
-    /// let src2 = [3i, 4, 5, 6];
-    /// assert!(dst.clone_from_slice(&src2) == 3);
-    /// assert!(dst == [3i, 4, 5]);
-    /// ```
-    #[experimental]
-    fn clone_from_slice(&mut self, &[T]) -> uint;
-}
-
 
-#[unstable = "trait is unstable"]
-impl<T: Clone> CloneSliceExt<T> for [T] {
     /// Returns a copy of `v`.
     #[inline]
-    fn to_vec(&self) -> Vec<T> {
+    fn to_vec(&self) -> Vec<T> where T: Clone {
         let mut vector = Vec::with_capacity(self.len());
         vector.push_all(self);
         vector
@@ -874,132 +962,71 @@ impl<T: Clone> CloneSliceExt<T> for [T] {
 
 
     #[inline]
-    fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
+    fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool, T: Clone {
         self.iter().cloned().partition(f)
     }
 
     /// Returns an iterator over all permutations of a vector.
-    fn permutations(&self) -> Permutations<T> {
+    fn permutations(&self) -> Permutations<T> where T: Clone {
         Permutations{
             swaps: ElementSwaps::new(self.len()),
             v: self.to_vec(),
         }
     }
 
-    fn clone_from_slice(&mut self, src: &[T]) -> uint {
-        core_slice::CloneSliceExt::clone_from_slice(self, src)
+    fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone {
+        core_slice::SliceExt::clone_from_slice(self, src)
     }
-}
 
-/// Allocating extension methods for slices on Ord values.
-#[unstable = "likely to merge with SliceExt"]
-pub trait OrdSliceExt<T> for Sized? {
-    /// Sorts the slice, in place.
-    ///
-    /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// let mut v = [-5i, 4, 1, -3, 2];
-    ///
-    /// v.sort();
-    /// assert!(v == [-5i, -3, 1, 2, 4]);
-    /// ```
-    #[stable]
-    fn sort(&mut self);
+    #[inline]
+    fn sort(&mut self) where T: Ord {
+        self.sort_by(|a, b| a.cmp(b))
+    }
 
-    /// Binary search a sorted slice for a given element.
-    ///
-    /// If the value is found then `Ok` is returned, containing the
-    /// index of the matching element; if the value is not found then
-    /// `Err` is returned, containing the index where a matching
-    /// element could be inserted while maintaining sorted order.
-    ///
-    /// # Example
-    ///
-    /// Looks up a series of four elements. The first is found, with a
-    /// uniquely determined position; the second and third are not
-    /// found; the fourth could match any position in `[1,4]`.
-    ///
-    /// ```rust
-    /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
-    /// let s = s.as_slice();
-    ///
-    /// assert_eq!(s.binary_search(&13),  Ok(9));
-    /// assert_eq!(s.binary_search(&4),   Err(7));
-    /// assert_eq!(s.binary_search(&100), Err(13));
-    /// let r = s.binary_search(&1);
-    /// assert!(match r { Ok(1...4) => true, _ => false, });
-    /// ```
-    #[stable]
-    fn binary_search(&self, x: &T) -> Result<uint, uint>;
+    fn binary_search(&self, x: &T) -> Result<uint, uint> where T: Ord {
+        core_slice::SliceExt::binary_search(self, x)
+    }
 
-    /// Deprecated: use `binary_search` instead.
-    #[deprecated = "use binary_search instead"]
-    fn binary_search_elem(&self, x: &T) -> Result<uint, uint> {
-        self.binary_search(x)
+    fn next_permutation(&mut self) -> bool where T: Ord {
+        core_slice::SliceExt::next_permutation(self)
     }
 
-    /// Mutates the slice to the next lexicographic permutation.
-    ///
-    /// Returns `true` if successful and `false` if the slice is at the
-    /// last-ordered permutation.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let v: &mut [_] = &mut [0i, 1, 2];
-    /// v.next_permutation();
-    /// let b: &mut [_] = &mut [0i, 2, 1];
-    /// assert!(v == b);
-    /// v.next_permutation();
-    /// let b: &mut [_] = &mut [1i, 0, 2];
-    /// assert!(v == b);
-    /// ```
-    #[unstable = "uncertain if this merits inclusion in std"]
-    fn next_permutation(&mut self) -> bool;
+    fn prev_permutation(&mut self) -> bool where T: Ord {
+        core_slice::SliceExt::prev_permutation(self)
+    }
 
-    /// Mutates the slice to the previous lexicographic permutation.
-    ///
-    /// Returns `true` if successful and `false` if the slice is at the
-    /// first-ordered permutation.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let v: &mut [_] = &mut [1i, 0, 2];
-    /// v.prev_permutation();
-    /// let b: &mut [_] = &mut [0i, 2, 1];
-    /// assert!(v == b);
-    /// v.prev_permutation();
-    /// let b: &mut [_] = &mut [0i, 1, 2];
-    /// assert!(v == b);
-    /// ```
-    #[unstable = "uncertain if this merits inclusion in std"]
-    fn prev_permutation(&mut self) -> bool;
-}
+    fn position_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
+        core_slice::SliceExt::position_elem(self, t)
+    }
 
-#[unstable = "trait is unstable"]
-impl<T: Ord> OrdSliceExt<T> for [T] {
-    #[inline]
-    fn sort(&mut self) {
-        self.sort_by(|a, b| a.cmp(b))
+    fn rposition_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
+        core_slice::SliceExt::rposition_elem(self, t)
     }
 
-    fn binary_search(&self, x: &T) -> Result<uint, uint> {
-        core_slice::OrdSliceExt::binary_search(self, x)
+    fn contains(&self, x: &T) -> bool where T: PartialEq {
+        core_slice::SliceExt::contains(self, x)
     }
 
-    fn next_permutation(&mut self) -> bool {
-        core_slice::OrdSliceExt::next_permutation(self)
+    fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
+        core_slice::SliceExt::starts_with(self, needle)
     }
 
-    fn prev_permutation(&mut self) -> bool {
-        core_slice::OrdSliceExt::prev_permutation(self)
+    fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
+        core_slice::SliceExt::ends_with(self, needle)
+    }
+
+    fn into_vec(mut self: Box<Self>) -> Vec<T> {
+        unsafe {
+            let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
+            mem::forget(self);
+            xs
+        }
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Extension traits for slices over specifc kinds of data
+////////////////////////////////////////////////////////////////////////////////
 #[unstable = "U should be an associated type"]
 /// An extension trait for concatenating slices
 pub trait SliceConcatExt<Sized? T, U> for Sized? {
@@ -1419,7 +1446,7 @@ mod tests {
     use std::boxed::Box;
     use prelude::{Some, None, range, Vec, ToString, Clone, Greater, Less, Equal};
     use prelude::{SliceExt, Iterator, IteratorExt, DoubleEndedIteratorExt};
-    use prelude::{OrdSliceExt, CloneSliceExt, PartialEqSliceExt, AsSlice};
+    use prelude::AsSlice;
     use prelude::{RandomAccessIterator, Ord, SliceConcatExt};
     use core::cell::Cell;
     use core::default::Default;
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 37a6e690f5d..769679ec4d4 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -17,17 +17,18 @@
 use core::prelude::*;
 
 use core::borrow::{Cow, IntoCow};
+use core::cmp::Equiv;
 use core::default::Default;
 use core::fmt;
 use core::hash;
+use core::iter::FromIterator;
 use core::mem;
+use core::ops::{mod, Deref, Add};
 use core::ptr;
-use core::ops;
 use core::raw::Slice as RawSlice;
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
-use slice::CloneSliceExt;
 use str::{mod, CharRange, FromStr, Utf8Error};
 use vec::{DerefVec, Vec, as_vec};
 
@@ -94,7 +95,7 @@ impl String {
     #[inline]
     #[experimental = "needs investigation to see if to_string() can match perf"]
     pub fn from_str(string: &str) -> String {
-        String { vec: string.as_bytes().to_vec() }
+        String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) }
     }
 
     /// Returns the vector as a string buffer, if possible, taking care not to
@@ -141,14 +142,18 @@ impl String {
     /// ```
     #[stable]
     pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> {
+        let mut i = 0;
         match str::from_utf8(v) {
             Ok(s) => return Cow::Borrowed(s),
-            Err(..) => {}
+            Err(e) => {
+                if let Utf8Error::InvalidByte(firstbad) = e {
+                    i = firstbad;
+                }
+            }
         }
 
         static TAG_CONT_U8: u8 = 128u8;
         static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
-        let mut i = 0;
         let total = v.len();
         fn unsafe_get(xs: &[u8], i: uint) -> u8 {
             unsafe { *xs.get_unchecked(i) }
@@ -172,7 +177,7 @@ impl String {
         // subseqidx is the index of the first byte of the subsequence we're looking at.
         // It's used to copy a bunch of contiguous good codepoints at once instead of copying
         // them one by one.
-        let mut subseqidx = 0;
+        let mut subseqidx = i;
 
         while i < total {
             let i_ = i;
@@ -936,7 +941,9 @@ impl ops::Slice<uint, str> for String {
 }
 
 #[experimental = "waiting on Deref stabilization"]
-impl ops::Deref<str> for String {
+impl ops::Deref for String {
+    type Target = str;
+
     fn deref<'a>(&'a self) -> &'a str {
         unsafe { mem::transmute(self.vec[]) }
     }
@@ -948,7 +955,9 @@ pub struct DerefString<'a> {
     x: DerefVec<'a, u8>
 }
 
-impl<'a> Deref<String> for DerefString<'a> {
+impl<'a> Deref for DerefString<'a> {
+    type Target = String;
+
     fn deref<'b>(&'b self) -> &'b String {
         unsafe { mem::transmute(&*self.x) }
     }
@@ -995,9 +1004,11 @@ pub trait ToString {
 
 impl<T: fmt::Show> ToString for T {
     fn to_string(&self) -> String {
-        let mut buf = Vec::<u8>::new();
-        let _ = fmt::write(&mut buf, format_args!("{}", *self));
-        String::from_utf8(buf).unwrap()
+        use core::fmt::Writer;
+        let mut buf = String::new();
+        let _ = buf.write_fmt(format_args!("{}", self));
+        buf.shrink_to_fit();
+        buf
     }
 }
 
@@ -1073,6 +1084,13 @@ impl<'a> Str for CowString<'a> {
     }
 }
 
+impl fmt::Writer for String {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        self.push_str(s);
+        Ok(())
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use prelude::*;
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index a1952352bad..7e367927421 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -50,21 +50,21 @@ use alloc::boxed::Box;
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
 use core::borrow::{Cow, IntoCow};
 use core::cmp::max;
+use core::cmp::{Equiv, Ordering};
 use core::default::Default;
 use core::fmt;
 use core::hash::{mod, Hash};
-use core::iter::repeat;
+use core::iter::{repeat, FromIterator};
 use core::kinds::marker::{ContravariantLifetime, InvariantType};
 use core::mem;
 use core::nonzero::NonZero;
 use core::num::{Int, UnsignedInt};
+use core::ops::{Index, IndexMut, Deref, Add};
 use core::ops;
 use core::ptr;
 use core::raw::Slice as RawSlice;
 use core::uint;
 
-use slice::CloneSliceExt;
-
 /// A growable list type, written `Vec<T>` but pronounced 'vector.'
 ///
 /// # Examples
@@ -1218,7 +1218,7 @@ unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
 
 #[unstable]
 impl<T:Clone> Clone for Vec<T> {
-    fn clone(&self) -> Vec<T> { self.as_slice().to_vec() }
+    fn clone(&self) -> Vec<T> { ::slice::SliceExt::to_vec(self.as_slice()) }
 
     fn clone_from(&mut self, other: &Vec<T>) {
         // drop anything in self that will not be overwritten
@@ -1303,12 +1303,14 @@ impl<T> ops::SliceMut<uint, [T]> for Vec<T> {
 }
 
 #[experimental = "waiting on Deref stability"]
-impl<T> ops::Deref<[T]> for Vec<T> {
+impl<T> ops::Deref for Vec<T> {
+    type Target = [T];
+
     fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() }
 }
 
 #[experimental = "waiting on DerefMut stability"]
-impl<T> ops::DerefMut<[T]> for Vec<T> {
+impl<T> ops::DerefMut for Vec<T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
 }
 
@@ -1488,9 +1490,9 @@ impl<T:fmt::Show> fmt::Show for Vec<T> {
     }
 }
 
-impl<'a> fmt::FormatWriter for Vec<u8> {
-    fn write(&mut self, buf: &[u8]) -> fmt::Result {
-        self.push_all(buf);
+impl<'a> fmt::Writer for Vec<u8> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        self.push_all(s.as_bytes());
         Ok(())
     }
 }
@@ -1718,7 +1720,9 @@ pub struct DerefVec<'a, T> {
 }
 
 #[experimental]
-impl<'a, T> Deref<Vec<T>> for DerefVec<'a, T> {
+impl<'a, T> Deref for DerefVec<'a, T> {
+    type Target = Vec<T>;
+
     fn deref<'b>(&'b self) -> &'b Vec<T> {
         &self.x
     }
@@ -2263,7 +2267,7 @@ mod tests {
             }
         }
         const NUM_ELEMENTS: uint = 2;
-        static DROP_COUNTER: AtomicUint = atomic::INIT_ATOMIC_UINT;
+        static DROP_COUNTER: AtomicUint = atomic::ATOMIC_UINT_INIT;
 
         let v = Vec::from_elem(NUM_ELEMENTS, Nothing);
 
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 7c30912cf91..172fd56ed39 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -15,12 +15,14 @@
 
 use core::prelude::*;
 
+use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
 use core::hash::{Hash, Writer};
+use core::iter::{Enumerate, FilterMap, Map, FromIterator};
 use core::iter;
-use core::iter::{Enumerate, FilterMap, Map};
 use core::mem::replace;
+use core::ops::{Index, IndexMut};
 
 use {vec, slice};
 use vec::Vec;
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 28563a60b61..ba7714ad9bc 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -54,7 +54,7 @@ macro_rules! array_impls {
             #[stable]
             impl<'a, A, B, Rhs> PartialEq<Rhs> for [A; $N] where
                 A: PartialEq<B>,
-                Rhs: Deref<[B]>,
+                Rhs: Deref<Target=[B]>,
             {
                 #[inline(always)]
                 fn eq(&self, other: &Rhs) -> bool { PartialEq::eq(self[], &**other) }
@@ -65,7 +65,7 @@ macro_rules! array_impls {
             #[stable]
             impl<'a, A, B, Lhs> PartialEq<[B; $N]> for Lhs where
                 A: PartialEq<B>,
-                Lhs: Deref<[A]>
+                Lhs: Deref<Target=[A]>
             {
                 #[inline(always)]
                 fn eq(&self, other: &[B; $N]) -> bool { PartialEq::eq(&**self, other[]) }
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index 6a40915f4dd..f653998c9bf 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -89,17 +89,27 @@ pub enum Ordering {
 
 /// An `AtomicBool` initialized to `false`.
 #[unstable = "may be renamed, pending conventions for static initalizers"]
-pub const INIT_ATOMIC_BOOL: AtomicBool =
+pub const ATOMIC_BOOL_INIT: AtomicBool =
         AtomicBool { v: UnsafeCell { value: 0 } };
 /// An `AtomicInt` initialized to `0`.
 #[unstable = "may be renamed, pending conventions for static initalizers"]
-pub const INIT_ATOMIC_INT: AtomicInt =
+pub const ATOMIC_INT_INIT: AtomicInt =
         AtomicInt { v: UnsafeCell { value: 0 } };
 /// An `AtomicUint` initialized to `0`.
 #[unstable = "may be renamed, pending conventions for static initalizers"]
-pub const INIT_ATOMIC_UINT: AtomicUint =
+pub const ATOMIC_UINT_INIT: AtomicUint =
         AtomicUint { v: UnsafeCell { value: 0, } };
 
+/// Deprecated
+#[deprecated = "renamed to ATOMIC_BOOL_INIT"]
+pub const INIT_ATOMIC_BOOL: AtomicBool = ATOMIC_BOOL_INIT;
+/// Deprecated
+#[deprecated = "renamed to ATOMIC_INT_INIT"]
+pub const INIT_ATOMIC_INT: AtomicInt = ATOMIC_INT_INIT;
+/// Deprecated
+#[deprecated = "renamed to ATOMIC_UINT_INIT"]
+pub const INIT_ATOMIC_UINT: AtomicUint = ATOMIC_UINT_INIT;
+
 // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
 const UINT_TRUE: uint = -1;
 
diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs
index 3a2cb8ea7d9..7e4d73d598d 100644
--- a/src/libcore/borrow.rs
+++ b/src/libcore/borrow.rs
@@ -191,7 +191,9 @@ impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned<T> {
     }
 }
 
-impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T>  {
+impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned<T>  {
+    type Target = B;
+
     fn deref(&self) -> &B {
         match *self {
             Borrowed(borrowed) => borrowed,
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 4b246860006..47204dfc422 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -155,6 +155,8 @@
 // FIXME: Can't be shared between threads. Dynamic borrows
 // FIXME: Relationship to Atomic types and RWLock
 
+#![stable]
+
 use clone::Clone;
 use cmp::PartialEq;
 use default::Default;
@@ -422,7 +424,9 @@ pub struct Ref<'b, T:'b> {
 }
 
 #[unstable = "waiting for `Deref` to become stable"]
-impl<'b, T> Deref<T> for Ref<'b, T> {
+impl<'b, T> Deref for Ref<'b, T> {
+    type Target = T;
+
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
         self._value
@@ -478,7 +482,9 @@ pub struct RefMut<'b, T:'b> {
 }
 
 #[unstable = "waiting for `Deref` to become stable"]
-impl<'b, T> Deref<T> for RefMut<'b, T> {
+impl<'b, T> Deref for RefMut<'b, T> {
+    type Target = T;
+
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
         self._value
@@ -486,7 +492,7 @@ impl<'b, T> Deref<T> for RefMut<'b, T> {
 }
 
 #[unstable = "waiting for `DerefMut` to become stable"]
-impl<'b, T> DerefMut<T> for RefMut<'b, T> {
+impl<'b, T> DerefMut for RefMut<'b, T> {
     #[inline]
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         self._value
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 5d84d0c7797..159c2a505d5 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -25,7 +25,7 @@ use kinds::Sized;
 
 /// A common trait for cloning an object.
 #[stable]
-pub trait Clone {
+pub trait Clone : Sized {
     /// Returns a copy of the value.
     #[stable]
     fn clone(&self) -> Self;
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 367c794e84b..38906892a33 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -125,11 +125,12 @@ impl Ordering {
     /// # Example
     ///
     /// ```rust
+    /// use std::cmp::Ordering::{Less, Equal, Greater};
+    ///
     /// assert_eq!(Less.reverse(), Greater);
     /// assert_eq!(Equal.reverse(), Equal);
     /// assert_eq!(Greater.reverse(), Less);
     ///
-    ///
     /// let mut data: &mut [_] = &mut [2u, 10, 5, 8];
     ///
     /// // sort the array from largest to smallest.
@@ -170,6 +171,8 @@ pub trait Ord for Sized?: Eq + PartialOrd<Self> {
     /// the expression `self <operator> other` if true.  For example:
     ///
     /// ```
+    /// use std::cmp::Ordering::{Less, Equal, Greater};
+    ///
     /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
     /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
     /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index e1728d762ed..a39168ec1ec 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -23,7 +23,7 @@ use num::FpCategory as Fp;
 use ops::FnOnce;
 use result::Result::Ok;
 use slice::{mod, SliceExt};
-use str::StrExt;
+use str::{mod, StrExt};
 
 /// A flag that specifies whether to use exponential (scientific) notation.
 pub enum ExponentFormat {
@@ -95,7 +95,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
     exp_upper: bool,
     f: F
 ) -> U where
-    F: FnOnce(&[u8]) -> U,
+    F: FnOnce(&str) -> U,
 {
     assert!(2 <= radix && radix <= 36);
     match exp_format {
@@ -109,12 +109,12 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
     let _1: T = Float::one();
 
     match num.classify() {
-        Fp::Nan => return f("NaN".as_bytes()),
+        Fp::Nan => return f("NaN"),
         Fp::Infinite if num > _0 => {
-            return f("inf".as_bytes());
+            return f("inf");
         }
         Fp::Infinite if num < _0 => {
-            return f("-inf".as_bytes());
+            return f("-inf");
         }
         _ => {}
     }
@@ -314,11 +314,11 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
                 end: &'a mut uint,
             }
 
-            impl<'a> fmt::FormatWriter for Filler<'a> {
-                fn write(&mut self, bytes: &[u8]) -> fmt::Result {
+            impl<'a> fmt::Writer for Filler<'a> {
+                fn write_str(&mut self, s: &str) -> fmt::Result {
                     slice::bytes::copy_memory(self.buf.slice_from_mut(*self.end),
-                                              bytes);
-                    *self.end += bytes.len();
+                                              s.as_bytes());
+                    *self.end += s.len();
                     Ok(())
                 }
             }
@@ -332,5 +332,5 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
         }
     }
 
-    f(buf[..end])
+    f(unsafe { str::from_utf8_unchecked(buf[..end]) })
 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 87fcb12e29f..13fbf5232f8 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -24,7 +24,7 @@ use result::Result::{Ok, Err};
 use result;
 use slice::SliceExt;
 use slice;
-use str::{StrExt, Utf8Error};
+use str::{mod, StrExt, Utf8Error};
 
 pub use self::num::radix;
 pub use self::num::Radix;
@@ -57,7 +57,7 @@ pub struct Error;
 /// library. The `write!` macro accepts an instance of `io::Writer`, and the
 /// `io::Writer` trait is favored over implementing this trait.
 #[experimental = "waiting for core and I/O reconciliation"]
-pub trait FormatWriter {
+pub trait Writer {
     /// Writes a slice of bytes into this writer, returning whether the write
     /// succeeded.
     ///
@@ -68,13 +68,32 @@ pub trait FormatWriter {
     /// # Errors
     ///
     /// This function will return an instance of `FormatError` on error.
-    fn write(&mut self, bytes: &[u8]) -> Result;
+    fn write_str(&mut self, s: &str) -> Result;
 
     /// Glue for usage of the `write!` macro with implementers of this trait.
     ///
     /// This method should generally not be invoked manually, but rather through
     /// the `write!` macro itself.
-    fn write_fmt(&mut self, args: Arguments) -> Result { write(self, args) }
+    fn write_fmt(&mut self, args: Arguments) -> Result {
+        // This Adapter is needed to allow `self` (of type `&mut
+        // Self`) to be cast to a FormatWriter (below) without
+        // requiring a `Sized` bound.
+        struct Adapter<'a,Sized? T:'a>(&'a mut T);
+
+        impl<'a, Sized? T> Writer for Adapter<'a, T>
+            where T: Writer
+        {
+            fn write_str(&mut self, s: &str) -> Result {
+                self.0.write_str(s)
+            }
+
+            fn write_fmt(&mut self, args: Arguments) -> Result {
+                self.0.write_fmt(args)
+            }
+        }
+
+        write(&mut Adapter(self), args)
+    }
 }
 
 /// A struct to represent both where to emit formatting strings to and how they
@@ -88,7 +107,7 @@ pub struct Formatter<'a> {
     width: Option<uint>,
     precision: Option<uint>,
 
-    buf: &'a mut (FormatWriter+'a),
+    buf: &'a mut (Writer+'a),
     curarg: slice::Iter<'a, Argument<'a>>,
     args: &'a [Argument<'a>],
 }
@@ -258,17 +277,6 @@ pub trait UpperExp for Sized? {
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
-static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument {
-    position: rt::ArgumentNext,
-    format: rt::FormatSpec {
-        fill: ' ',
-        align: rt::AlignUnknown,
-        flags: 0,
-        precision: rt::CountImplied,
-        width: rt::CountImplied,
-    }
-};
-
 /// The `write` function takes an output stream, a precompiled format string,
 /// and a list of arguments. The arguments will be formatted according to the
 /// specified format string into the output stream provided.
@@ -279,7 +287,7 @@ static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument {
 ///   * args - the precompiled arguments generated by `format_args!`
 #[experimental = "libcore and I/O have yet to be reconciled, and this is an \
                   implementation detail which should not otherwise be exported"]
-pub fn write(output: &mut FormatWriter, args: Arguments) -> Result {
+pub fn write(output: &mut Writer, args: Arguments) -> Result {
     let mut formatter = Formatter {
         flags: 0,
         width: None,
@@ -296,16 +304,16 @@ pub fn write(output: &mut FormatWriter, args: Arguments) -> Result {
     match args.fmt {
         None => {
             // We can use default formatting parameters for all arguments.
-            for _ in range(0, args.args.len()) {
-                try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
-                try!(formatter.run(&DEFAULT_ARGUMENT));
+            for (arg, piece) in args.args.iter().zip(pieces.by_ref()) {
+                try!(formatter.buf.write_str(*piece));
+                try!((arg.formatter)(arg.value, &mut formatter));
             }
         }
         Some(fmt) => {
             // Every spec has a corresponding argument that is preceded by
             // a string piece.
             for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
-                try!(formatter.buf.write(piece.as_bytes()));
+                try!(formatter.buf.write_str(*piece));
                 try!(formatter.run(arg));
             }
         }
@@ -314,7 +322,7 @@ pub fn write(output: &mut FormatWriter, args: Arguments) -> Result {
     // There can be only one trailing string piece left.
     match pieces.next() {
         Some(piece) => {
-            try!(formatter.buf.write(piece.as_bytes()));
+            try!(formatter.buf.write_str(*piece));
         }
         None => {}
     }
@@ -378,7 +386,7 @@ impl<'a> Formatter<'a> {
     pub fn pad_integral(&mut self,
                         is_positive: bool,
                         prefix: &str,
-                        buf: &[u8])
+                        buf: &str)
                         -> Result {
         use char::Char;
         use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
@@ -402,9 +410,10 @@ impl<'a> Formatter<'a> {
             for c in sign.into_iter() {
                 let mut b = [0; 4];
                 let n = c.encode_utf8(&mut b).unwrap_or(0);
-                try!(f.buf.write(b[..n]));
+                let b = unsafe { str::from_utf8_unchecked(b[0..n]) };
+                try!(f.buf.write_str(b));
             }
-            if prefixed { f.buf.write(prefix.as_bytes()) }
+            if prefixed { f.buf.write_str(prefix) }
             else { Ok(()) }
         };
 
@@ -413,24 +422,26 @@ impl<'a> Formatter<'a> {
             // If there's no minimum length requirements then we can just
             // write the bytes.
             None => {
-                try!(write_prefix(self)); self.buf.write(buf)
+                try!(write_prefix(self)); self.buf.write_str(buf)
             }
             // Check if we're over the minimum width, if so then we can also
             // just write the bytes.
             Some(min) if width >= min => {
-                try!(write_prefix(self)); self.buf.write(buf)
+                try!(write_prefix(self)); self.buf.write_str(buf)
             }
             // The sign and prefix goes before the padding if the fill character
             // is zero
             Some(min) if self.flags & (1 << (FlagSignAwareZeroPad as uint)) != 0 => {
                 self.fill = '0';
                 try!(write_prefix(self));
-                self.with_padding(min - width, rt::AlignRight, |f| f.buf.write(buf))
+                self.with_padding(min - width, rt::AlignRight, |f| {
+                    f.buf.write_str(buf)
+                })
             }
             // Otherwise, the sign and prefix goes after the padding
             Some(min) => {
                 self.with_padding(min - width, rt::AlignRight, |f| {
-                    try!(write_prefix(f)); f.buf.write(buf)
+                    try!(write_prefix(f)); f.buf.write_str(buf)
                 })
             }
         }
@@ -451,7 +462,7 @@ impl<'a> Formatter<'a> {
     pub fn pad(&mut self, s: &str) -> Result {
         // Make sure there's a fast path up front
         if self.width.is_none() && self.precision.is_none() {
-            return self.buf.write(s.as_bytes());
+            return self.buf.write_str(s);
         }
         // The `precision` field can be interpreted as a `max-width` for the
         // string being formatted
@@ -463,7 +474,7 @@ impl<'a> Formatter<'a> {
                 let char_len = s.char_len();
                 if char_len >= max {
                     let nchars = ::cmp::min(max, char_len);
-                    return self.buf.write(s.slice_chars(0, nchars).as_bytes());
+                    return self.buf.write_str(s.slice_chars(0, nchars));
                 }
             }
             None => {}
@@ -472,17 +483,17 @@ impl<'a> Formatter<'a> {
         match self.width {
             // If we're under the maximum length, and there's no minimum length
             // requirements, then we can just emit the string
-            None => self.buf.write(s.as_bytes()),
+            None => self.buf.write_str(s),
             // If we're under the maximum width, check if we're over the minimum
             // width, if so it's as easy as just emitting the string.
             Some(width) if s.char_len() >= width => {
-                self.buf.write(s.as_bytes())
+                self.buf.write_str(s)
             }
             // If we're under both the maximum and the minimum width, then fill
             // up the minimum width with the specified string + some alignment.
             Some(width) => {
                 self.with_padding(width - s.char_len(), rt::AlignLeft, |me| {
-                    me.buf.write(s.as_bytes())
+                    me.buf.write_str(s)
                 })
             }
         }
@@ -507,15 +518,16 @@ impl<'a> Formatter<'a> {
 
         let mut fill = [0u8; 4];
         let len = self.fill.encode_utf8(&mut fill).unwrap_or(0);
+        let fill = unsafe { str::from_utf8_unchecked(fill[..len]) };
 
         for _ in range(0, pre_pad) {
-            try!(self.buf.write(fill[..len]));
+            try!(self.buf.write_str(fill));
         }
 
         try!(f(self));
 
         for _ in range(0, post_pad) {
-            try!(self.buf.write(fill[..len]));
+            try!(self.buf.write_str(fill));
         }
 
         Ok(())
@@ -524,8 +536,8 @@ impl<'a> Formatter<'a> {
     /// Writes some data to the underlying buffer contained within this
     /// formatter.
     #[unstable = "reconciling core and I/O may alter this definition"]
-    pub fn write(&mut self, data: &[u8]) -> Result {
-        self.buf.write(data)
+    pub fn write_str(&mut self, data: &str) -> Result {
+        self.buf.write_str(data)
     }
 
     /// Writes some formatted information into this instance
@@ -586,9 +598,6 @@ impl<'a, Sized? T: Show> Show for &'a T {
 impl<'a, Sized? T: Show> Show for &'a mut T {
     fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
 }
-impl<'a> Show for &'a (Show+'a) {
-    fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
-}
 
 impl Show for bool {
     fn fmt(&self, f: &mut Formatter) -> Result {
@@ -616,7 +625,9 @@ impl Show for char {
 impl<T> Pointer for *const T {
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.flags |= 1 << (rt::FlagAlternate as uint);
-        LowerHex::fmt(&(*self as uint), f)
+        let ret = LowerHex::fmt(&(*self as uint), f);
+        f.flags &= !(1 << (rt::FlagAlternate as uint));
+        ret
     }
 }
 
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 7de3e847dc6..4f0cecbb243 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -18,6 +18,7 @@ use fmt;
 use iter::DoubleEndedIteratorExt;
 use num::{Int, cast};
 use slice::SliceExt;
+use str;
 
 /// A type that represents a specific radix
 #[doc(hidden)]
@@ -60,7 +61,8 @@ trait GenericRadix {
                 if x == zero { break };                   // No more digits left to accumulate.
             }
         }
-        f.pad_integral(is_positive, self.prefix(), buf[curr..])
+        let buf = unsafe { str::from_utf8_unchecked(buf[curr..]) };
+        f.pad_integral(is_positive, self.prefix(), buf)
     }
 }
 
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 7c53503b1ce..d7a675b3104 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -54,7 +54,7 @@
 //!
 //! This `for` loop syntax can be applied to any iterator over any type.
 
-pub use self::MinMaxResult::*;
+use self::MinMaxResult::*;
 
 use clone::Clone;
 use cmp;
@@ -65,6 +65,7 @@ use num::{ToPrimitive, Int};
 use ops::{Add, Deref, FnMut};
 use option::Option;
 use option::Option::{Some, None};
+use std::kinds::Sized;
 use uint;
 
 #[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;
@@ -109,7 +110,7 @@ pub trait Extend<A> {
 
 #[unstable = "new convention for extension traits"]
 /// An extension trait providing numerous methods applicable to all iterators.
-pub trait IteratorExt<A>: Iterator<A> {
+pub trait IteratorExt<A>: Iterator<A> + Sized {
     /// Chain this iterator with another, returning a new iterator that will
     /// finish iterating over the current iterator, and then iterate
     /// over the other specified iterator.
@@ -692,7 +693,7 @@ impl<A, I> IteratorExt<A> for I where I: Iterator<A> {}
 
 /// Extention trait for iterators of pairs.
 #[unstable = "newly added trait, likely to be merged with IteratorExt"]
-pub trait IteratorPairExt<A, B>: Iterator<(A, B)> {
+pub trait IteratorPairExt<A, B>: Iterator<(A, B)> + Sized {
     /// Converts an iterator of pairs into a pair of containers.
     ///
     /// Loops through the entire iterator, collecting the first component of
@@ -738,7 +739,7 @@ pub trait DoubleEndedIterator<A>: Iterator<A> {
 
 /// Extension methods for double-ended iterators.
 #[unstable = "new extension trait convention"]
-pub trait DoubleEndedIteratorExt<A>: DoubleEndedIterator<A> {
+pub trait DoubleEndedIteratorExt<A>: DoubleEndedIterator<A> + Sized {
     /// Change the direction of the iterator
     ///
     /// The flipped iterator swaps the ends on an iterator that can already
@@ -1035,7 +1036,7 @@ pub trait IteratorOrdExt<A> {
     /// # Example
     ///
     /// ```rust
-    /// use std::iter::{NoElements, OneElement, MinMax};
+    /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
     ///
     /// let v: [int; 0] = [];
     /// assert_eq!(v.iter().min_max(), NoElements);
@@ -1145,7 +1146,7 @@ impl<T: Clone> MinMaxResult<T> {
     /// # Example
     ///
     /// ```rust
-    /// use std::iter::{NoElements, OneElement, MinMax, MinMaxResult};
+    /// use std::iter::MinMaxResult::{mod, NoElements, OneElement, MinMax};
     ///
     /// let r: MinMaxResult<int> = NoElements;
     /// assert_eq!(r.into_option(), None);
@@ -1174,7 +1175,7 @@ pub trait IteratorCloneExt<A> {
 }
 
 #[unstable = "trait is unstable"]
-impl<A: Clone, D: Deref<A>, I: Iterator<D>> IteratorCloneExt<A> for I {
+impl<A: Clone, D: Deref<Target=A>, I: Iterator<D>> IteratorCloneExt<A> for I {
     fn cloned(self) -> Cloned<I> {
         Cloned { it: self }
     }
@@ -1185,7 +1186,7 @@ pub struct Cloned<I> {
     it: I,
 }
 
-impl<A: Clone, D: Deref<A>, I: Iterator<D>> Iterator<A> for Cloned<I> {
+impl<A: Clone, D: Deref<Target=A>, I: Iterator<D>> Iterator<A> for Cloned<I> {
     fn next(&mut self) -> Option<A> {
         self.it.next().cloned()
     }
@@ -1195,7 +1196,7 @@ impl<A: Clone, D: Deref<A>, I: Iterator<D>> Iterator<A> for Cloned<I> {
     }
 }
 
-impl<A: Clone, D: Deref<A>, I: DoubleEndedIterator<D>>
+impl<A: Clone, D: Deref<Target=A>, I: DoubleEndedIterator<D>>
         DoubleEndedIterator<A> for Cloned<I> {
     fn next_back(&mut self) -> Option<A> {
         self.it.next_back().cloned()
@@ -1203,7 +1204,7 @@ impl<A: Clone, D: Deref<A>, I: DoubleEndedIterator<D>>
 }
 
 #[unstable = "trait is unstable"]
-impl<A: Clone, D: Deref<A>, I: ExactSizeIterator<D>> ExactSizeIterator<A> for Cloned<I> {}
+impl<A: Clone, D: Deref<Target=A>, I: ExactSizeIterator<D>> ExactSizeIterator<A> for Cloned<I> {}
 
 #[unstable = "recently renamed for extension trait conventions"]
 /// An extension trait for cloneable iterators.
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index c429e4b8212..ba9103520d8 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -44,7 +44,9 @@ impl<T: Zeroable> NonZero<T> {
     }
 }
 
-impl<T: Zeroable> Deref<T> for NonZero<T> {
+impl<T: Zeroable> Deref for NonZero<T> {
+    type Target = T;
+
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
         let NonZero(ref inner) = *self;
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 0d2ce4f6071..d16478dd6cc 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -980,7 +980,7 @@ impl_to_primitive_float! { f64 }
 
 /// A generic trait for converting a number to a value.
 #[experimental = "trait is likely to be removed"]
-pub trait FromPrimitive {
+pub trait FromPrimitive : ::kinds::Sized {
     /// Convert an `int` to return an optional value of this type. If the
     /// value cannot be represented by this value, the `None` is returned.
     #[inline]
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index af07869e95f..b51d4d91c2f 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -25,6 +25,8 @@
 //! demonstrates adding and subtracting two `Point`s.
 //!
 //! ```rust
+//! use std::ops::{Add, Sub};
+//!
 //! #[deriving(Show)]
 //! struct Point {
 //!     x: int,
@@ -68,13 +70,13 @@ use option::Option::{mod, Some, None};
 /// struct HasDrop;
 ///
 /// impl Drop for HasDrop {
-///   fn drop(&mut self) {
-///       println!("Dropping!");
-///   }
+///     fn drop(&mut self) {
+///         println!("Dropping!");
+///     }
 /// }
 ///
 /// fn main() {
-///   let _x = HasDrop;
+///     let _x = HasDrop;
 /// }
 /// ```
 #[lang="drop"]
@@ -91,6 +93,8 @@ pub trait Drop {
 /// calling `add`, and therefore, `main` prints `Adding!`.
 ///
 /// ```rust
+/// use std::ops::Add;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -130,6 +134,8 @@ add_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `sub`, and therefore, `main` prints `Subtracting!`.
 ///
 /// ```rust
+/// use std::ops::Sub;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -169,6 +175,8 @@ sub_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `mul`, and therefore, `main` prints `Multiplying!`.
 ///
 /// ```rust
+/// use std::ops::Mul;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -208,6 +216,8 @@ mul_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `div`, and therefore, `main` prints `Dividing!`.
 ///
 /// ```
+/// use std::ops::Div;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -247,6 +257,8 @@ div_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
 ///
 /// ```
+/// use std::ops::Rem;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -300,6 +312,8 @@ rem_float_impl! { f64, fmod }
 /// `neg`, and therefore, `main` prints `Negating!`.
 ///
 /// ```
+/// use std::ops::Neg;
+///
 /// struct Foo;
 ///
 /// impl Copy for Foo {}
@@ -356,6 +370,8 @@ neg_uint_impl! { u64, i64 }
 /// `not`, and therefore, `main` prints `Not-ing!`.
 ///
 /// ```
+/// use std::ops::Not;
+///
 /// struct Foo;
 ///
 /// impl Copy for Foo {}
@@ -396,6 +412,8 @@ not_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
 ///
 /// ```
+/// use std::ops::BitAnd;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -435,6 +453,8 @@ bitand_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
 ///
 /// ```
+/// use std::ops::BitOr;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -474,6 +494,8 @@ bitor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
 ///
 /// ```
+/// use std::ops::BitXor;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -513,6 +535,8 @@ bitxor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `shl`, and therefore, `main` prints `Shifting left!`.
 ///
 /// ```
+/// use std::ops::Shl;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -554,6 +578,8 @@ shl_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `shr`, and therefore, `main` prints `Shifting right!`.
 ///
 /// ```
+/// use std::ops::Shr;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -594,6 +620,8 @@ shr_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `index`, and therefore, `main` prints `Indexing!`.
 ///
 /// ```
+/// use std::ops::Index;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -623,6 +651,8 @@ pub trait Index<Sized? Index, Sized? Result> for Sized? {
 /// calling `index_mut`, and therefore, `main` prints `Indexing!`.
 ///
 /// ```
+/// use std::ops::IndexMut;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -652,6 +682,8 @@ pub trait IndexMut<Sized? Index, Sized? Result> for Sized? {
 /// calling `slice_to`, and therefore, `main` prints `Slicing!`.
 ///
 /// ```ignore
+/// use std::ops::Slice;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -699,6 +731,8 @@ pub trait Slice<Sized? Idx, Sized? Result> for Sized? {
 /// calling `slice_from_mut`, and therefore, `main` prints `Slicing!`.
 ///
 /// ```ignore
+/// use std::ops::SliceMut;
+///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
@@ -827,11 +861,17 @@ pub struct RangeTo<Idx> {
 /// struct.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
+/// use std::ops::Deref;
+///
 /// struct DerefExample<T> {
 ///     value: T
 /// }
 ///
-/// impl<T> Deref<T> for DerefExample<T> {
+/// impl<T> Deref for DerefExample<T> {
+///     type Target = T;
+///
 ///     fn deref<'a>(&'a self) -> &'a T {
 ///         &self.value
 ///     }
@@ -843,16 +883,22 @@ pub struct RangeTo<Idx> {
 /// }
 /// ```
 #[lang="deref"]
-pub trait Deref<Sized? Result> for Sized? {
+pub trait Deref for Sized? {
+    type Sized? Target;
+
     /// The method called to dereference a value
-    fn deref<'a>(&'a self) -> &'a Result;
+    fn deref<'a>(&'a self) -> &'a Self::Target;
 }
 
-impl<'a, Sized? T> Deref<T> for &'a T {
+impl<'a, Sized? T> Deref for &'a T {
+    type Target = T;
+
     fn deref(&self) -> &T { *self }
 }
 
-impl<'a, Sized? T> Deref<T> for &'a mut T {
+impl<'a, Sized? T> Deref for &'a mut T {
+    type Target = T;
+
     fn deref(&self) -> &T { *self }
 }
 
@@ -865,17 +911,23 @@ impl<'a, Sized? T> Deref<T> for &'a mut T {
 /// struct.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
+/// use std::ops::{Deref, DerefMut};
+///
 /// struct DerefMutExample<T> {
 ///     value: T
 /// }
 ///
-/// impl<T> Deref<T> for DerefMutExample<T> {
+/// impl<T> Deref for DerefMutExample<T> {
+///     type Target = T;
+///
 ///     fn deref<'a>(&'a self) -> &'a T {
 ///         &self.value
 ///     }
 /// }
 ///
-/// impl<T> DerefMut<T> for DerefMutExample<T> {
+/// impl<T> DerefMut for DerefMutExample<T> {
 ///     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
 ///         &mut self.value
 ///     }
@@ -888,12 +940,12 @@ impl<'a, Sized? T> Deref<T> for &'a mut T {
 /// }
 /// ```
 #[lang="deref_mut"]
-pub trait DerefMut<Sized? Result> for Sized? : Deref<Result> {
+pub trait DerefMut for Sized? : Deref {
     /// The method called to mutably dereference a value
-    fn deref_mut<'a>(&'a mut self) -> &'a mut Result;
+    fn deref_mut<'a>(&'a mut self) -> &'a mut <Self as Deref>::Target;
 }
 
-impl<'a, Sized? T> DerefMut<T> for &'a mut T {
+impl<'a, Sized? T> DerefMut for &'a mut T {
     fn deref_mut(&mut self) -> &mut T { *self }
 }
 
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index d831a57893b..b9749f57d58 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -699,7 +699,7 @@ impl<T> Option<T> {
     }
 }
 
-impl<'a, T: Clone, D: Deref<T>> Option<D> {
+impl<'a, T: Clone, D: Deref<Target=T>> Option<D> {
     /// Maps an Option<D> to an Option<T> by dereffing and cloning the contents of the Option.
     /// Useful for converting an Option<&T> to an Option<T>.
     #[unstable = "recently added as part of collections reform"]
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index cecb4938153..8cb63138009 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -30,39 +30,23 @@
 
 // Reexported core operators
 pub use kinds::{Copy, Send, Sized, Sync};
-pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
-pub use ops::{BitAnd, BitOr, BitXor};
-pub use ops::{Drop, Deref, DerefMut};
-pub use ops::{Shl, Shr};
-pub use ops::{Index, IndexMut};
-pub use ops::{Slice, SliceMut};
-pub use ops::{Fn, FnMut, FnOnce};
+pub use ops::{Drop, Fn, FnMut, FnOnce};
 
 // Reexported functions
 pub use iter::range;
 pub use mem::drop;
-pub use str::from_str;
 
 // Reexported types and traits
 
 pub use char::Char;
 pub use clone::Clone;
 pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
-pub use cmp::{Ordering, Equiv};
-pub use cmp::Ordering::{Less, Equal, Greater};
-pub use iter::{FromIterator, Extend, IteratorExt};
-pub use iter::{Iterator, DoubleEndedIterator, DoubleEndedIteratorExt, RandomAccessIterator};
-pub use iter::{IteratorCloneExt, CloneIteratorExt, IteratorPairExt};
-pub use iter::{IteratorOrdExt, MutableDoubleEndedIterator, ExactSizeIterator};
-pub use num::{ToPrimitive, FromPrimitive};
-pub use option::Option;
-pub use option::Option::{Some, None};
+pub use iter::{Extend, IteratorExt};
+pub use iter::{Iterator, DoubleEndedIterator, DoubleEndedIteratorExt};
+pub use iter::{IteratorCloneExt, CloneIteratorExt};
+pub use iter::{IteratorOrdExt, ExactSizeIterator, IteratorPairExt};
+pub use option::Option::{mod, Some, None};
 pub use ptr::{PtrExt, MutPtrExt};
-pub use result::Result;
-pub use result::Result::{Ok, Err};
-pub use str::{Str, StrExt};
-pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
-pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
-pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
-pub use slice::{PartialEqSliceExt, OrdSliceExt};
+pub use result::Result::{mod, Ok, Err};
 pub use slice::{AsSlice, SliceExt};
+pub use str::{Str, StrExt};
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index faf1d781465..f29d7518149 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -92,7 +92,7 @@ use mem;
 use clone::Clone;
 use intrinsics;
 use option::Option::{mod, Some, None};
-use kinds::{Send, Sync};
+use kinds::{Send, Sized, Sync};
 
 use cmp::{PartialEq, Eq, Ord, PartialOrd, Equiv};
 use cmp::Ordering::{mod, Less, Equal, Greater};
@@ -243,7 +243,9 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 
 /// Methods on raw pointers
 #[stable]
-pub trait PtrExt<T> {
+pub trait PtrExt: Sized {
+    type Target;
+
     /// Returns the null pointer.
     #[deprecated = "call ptr::null instead"]
     fn null() -> Self;
@@ -271,7 +273,7 @@ pub trait PtrExt<T> {
     /// memory.
     #[unstable = "Option is not clearly the right return type, and we may want \
                   to tie the return lifetime to a borrow of the raw pointer"]
-    unsafe fn as_ref<'a>(&self) -> Option<&'a T>;
+    unsafe fn as_ref<'a>(&self) -> Option<&'a Self::Target>;
 
     /// Calculates the offset from a pointer. `count` is in units of T; e.g. a
     /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
@@ -287,7 +289,9 @@ pub trait PtrExt<T> {
 
 /// Methods on mutable raw pointers
 #[stable]
-pub trait MutPtrExt<T>{
+pub trait MutPtrExt {
+    type Target;
+
     /// Returns `None` if the pointer is null, or else returns a mutable
     /// reference to the value wrapped in `Some`.
     ///
@@ -297,11 +301,13 @@ pub trait MutPtrExt<T>{
     /// of the returned pointer.
     #[unstable = "Option is not clearly the right return type, and we may want \
                   to tie the return lifetime to a borrow of the raw pointer"]
-    unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
+    unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>;
 }
 
 #[stable]
-impl<T> PtrExt<T> for *const T {
+impl<T> PtrExt for *const T {
+    type Target = T;
+
     #[inline]
     #[deprecated = "call ptr::null instead"]
     fn null() -> *const T { null() }
@@ -333,7 +339,9 @@ impl<T> PtrExt<T> for *const T {
 }
 
 #[stable]
-impl<T> PtrExt<T> for *mut T {
+impl<T> PtrExt for *mut T {
+    type Target = T;
+
     #[inline]
     #[deprecated = "call ptr::null instead"]
     fn null() -> *mut T { null_mut() }
@@ -365,7 +373,9 @@ impl<T> PtrExt<T> for *mut T {
 }
 
 #[stable]
-impl<T> MutPtrExt<T> for *mut T {
+impl<T> MutPtrExt for *mut T {
+    type Target = T;
+
     #[inline]
     #[unstable = "return value does not necessarily convey all possible \
                   information"]
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 7d894ac697b..07addf7a569 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -64,57 +64,77 @@ use raw::Slice as RawSlice;
 
 /// Extension methods for slices.
 #[allow(missing_docs)] // docs in libcollections
-pub trait SliceExt<T> for Sized? {
-    fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T];
-    fn slice_from<'a>(&'a self, start: uint) -> &'a [T];
-    fn slice_to<'a>(&'a self, end: uint) -> &'a [T];
-    fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]);
-    fn iter<'a>(&'a self) -> Iter<'a, T>;
-    fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P>
-                    where P: FnMut(&T) -> bool;
-    fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P>
-                     where P: FnMut(&T) -> bool;
-    fn rsplitn<'a, P>(&'a self,  n: uint, pred: P) -> RSplitN<'a, T, P>
-                      where P: FnMut(&T) -> bool;
-    fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>;
-    fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>;
-    fn get<'a>(&'a self, index: uint) -> Option<&'a T>;
-    fn first<'a>(&'a self) -> Option<&'a T>;
-    fn tail<'a>(&'a self) -> &'a [T];
-    fn init<'a>(&'a self) -> &'a [T];
-    fn last<'a>(&'a self) -> Option<&'a T>;
-    unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T;
-    fn as_ptr(&self) -> *const T;
+pub trait SliceExt for Sized? {
+    type Item;
+
+    fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [Self::Item];
+    fn slice_from<'a>(&'a self, start: uint) -> &'a [Self::Item];
+    fn slice_to<'a>(&'a self, end: uint) -> &'a [Self::Item];
+    fn split_at<'a>(&'a self, mid: uint) -> (&'a [Self::Item], &'a [Self::Item]);
+    fn iter<'a>(&'a self) -> Iter<'a, Self::Item>;
+    fn split<'a, P>(&'a self, pred: P) -> Split<'a, Self::Item, P>
+                    where P: FnMut(&Self::Item) -> bool;
+    fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, Self::Item, P>
+                     where P: FnMut(&Self::Item) -> bool;
+    fn rsplitn<'a, P>(&'a self,  n: uint, pred: P) -> RSplitN<'a, Self::Item, P>
+                      where P: FnMut(&Self::Item) -> bool;
+    fn windows<'a>(&'a self, size: uint) -> Windows<'a, Self::Item>;
+    fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, Self::Item>;
+    fn get<'a>(&'a self, index: uint) -> Option<&'a Self::Item>;
+    fn first<'a>(&'a self) -> Option<&'a Self::Item>;
+    fn tail<'a>(&'a self) -> &'a [Self::Item];
+    fn init<'a>(&'a self) -> &'a [Self::Item];
+    fn last<'a>(&'a self) -> Option<&'a Self::Item>;
+    unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a Self::Item;
+    fn as_ptr(&self) -> *const Self::Item;
     fn binary_search_by<F>(&self, f: F) -> Result<uint, uint> where
-        F: FnMut(&T) -> Ordering;
+        F: FnMut(&Self::Item) -> Ordering;
     fn len(&self) -> uint;
     fn is_empty(&self) -> bool { self.len() == 0 }
-    fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>;
-    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T];
-    fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T];
-    fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T];
-    fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T];
-    fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>;
-    fn first_mut<'a>(&'a mut self) -> Option<&'a mut T>;
-    fn tail_mut<'a>(&'a mut self) -> &'a mut [T];
-    fn init_mut<'a>(&'a mut self) -> &'a mut [T];
-    fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>;
-    fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P>
-                        where P: FnMut(&T) -> bool;
-    fn splitn_mut<P>(&mut self, n: uint, pred: P) -> SplitNMut<T, P>
-                     where P: FnMut(&T) -> bool;
-    fn rsplitn_mut<P>(&mut self,  n: uint, pred: P) -> RSplitNMut<T, P>
-                      where P: FnMut(&T) -> bool;
-    fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T>;
+    fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut Self::Item>;
+    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item];
+    fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [Self::Item];
+    fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [Self::Item];
+    fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [Self::Item];
+    fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>;
+    fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
+    fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
+    fn init_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
+    fn last_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
+    fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, Self::Item, P>
+                        where P: FnMut(&Self::Item) -> bool;
+    fn splitn_mut<P>(&mut self, n: uint, pred: P) -> SplitNMut<Self::Item, P>
+                     where P: FnMut(&Self::Item) -> bool;
+    fn rsplitn_mut<P>(&mut self,  n: uint, pred: P) -> RSplitNMut<Self::Item, P>
+                      where P: FnMut(&Self::Item) -> bool;
+    fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, Self::Item>;
     fn swap(&mut self, a: uint, b: uint);
-    fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]);
+    fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [Self::Item], &'a mut [Self::Item]);
     fn reverse(&mut self);
-    unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T;
-    fn as_mut_ptr(&mut self) -> *mut T;
+    unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut Self::Item;
+    fn as_mut_ptr(&mut self) -> *mut Self::Item;
+
+    fn position_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
+
+    fn rposition_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
+
+    fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
+
+    fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+
+    fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+
+    fn binary_search(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord;
+    fn next_permutation(&mut self) -> bool where Self::Item: Ord;
+    fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
+
+    fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone;
 }
 
 #[unstable]
-impl<T> SliceExt<T> for [T] {
+impl<T> SliceExt for [T] {
+    type Item = T;
+
     #[inline]
     fn slice(&self, start: uint, end: uint) -> &[T] {
         assert!(start <= end);
@@ -404,153 +424,41 @@ impl<T> SliceExt<T> for [T] {
     fn as_mut_ptr(&mut self) -> *mut T {
         self.repr().data as *mut T
     }
-}
-
-impl<T> ops::Index<uint, T> for [T] {
-    fn index(&self, &index: &uint) -> &T {
-        assert!(index < self.len());
-
-        unsafe { mem::transmute(self.repr().data.offset(index as int)) }
-    }
-}
-
-impl<T> ops::IndexMut<uint, T> for [T] {
-    fn index_mut(&mut self, &index: &uint) -> &mut T {
-        assert!(index < self.len());
-
-        unsafe { mem::transmute(self.repr().data.offset(index as int)) }
-    }
-}
-
-impl<T> ops::Slice<uint, [T]> for [T] {
-    #[inline]
-    fn as_slice_<'a>(&'a self) -> &'a [T] {
-        self
-    }
-
-    #[inline]
-    fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
-        self.slice_or_fail(start, &self.len())
-    }
-
-    #[inline]
-    fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
-        self.slice_or_fail(&0, end)
-    }
-    #[inline]
-    fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
-        assert!(*start <= *end);
-        assert!(*end <= self.len());
-        unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(*start as int),
-                    len: (*end - *start)
-                })
-        }
-    }
-}
-
-impl<T> ops::SliceMut<uint, [T]> for [T] {
-    #[inline]
-    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
-        self
-    }
-
-    #[inline]
-    fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
-        let len = &self.len();
-        self.slice_or_fail_mut(start, len)
-    }
-
-    #[inline]
-    fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
-        self.slice_or_fail_mut(&0, end)
-    }
-    #[inline]
-    fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
-        assert!(*start <= *end);
-        assert!(*end <= self.len());
-        unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(*start as int),
-                    len: (*end - *start)
-                })
-        }
-    }
-}
-
-/// Extension methods for slices containing `PartialEq` elements.
-#[unstable = "may merge with SliceExt"]
-pub trait PartialEqSliceExt<T: PartialEq> for Sized? {
-    /// Find the first index containing a matching value.
-    #[experimental]
-    fn position_elem(&self, t: &T) -> Option<uint>;
-
-    /// Find the last index containing a matching value.
-    #[experimental]
-    fn rposition_elem(&self, t: &T) -> Option<uint>;
-
-    /// Return true if the slice contains an element with the given value.
-    #[stable]
-    fn contains(&self, x: &T) -> bool;
-
-    /// Returns true if `needle` is a prefix of the slice.
-    #[stable]
-    fn starts_with(&self, needle: &[T]) -> bool;
-
-    /// Returns true if `needle` is a suffix of the slice.
-    #[stable]
-    fn ends_with(&self, needle: &[T]) -> bool;
-}
 
-#[unstable = "trait is unstable"]
-impl<T: PartialEq> PartialEqSliceExt<T> for [T] {
     #[inline]
-    fn position_elem(&self, x: &T) -> Option<uint> {
+    fn position_elem(&self, x: &T) -> Option<uint> where T: PartialEq {
         self.iter().position(|y| *x == *y)
     }
 
     #[inline]
-    fn rposition_elem(&self, t: &T) -> Option<uint> {
+    fn rposition_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
         self.iter().rposition(|x| *x == *t)
     }
 
     #[inline]
-    fn contains(&self, x: &T) -> bool {
+    fn contains(&self, x: &T) -> bool where T: PartialEq {
         self.iter().any(|elt| *x == *elt)
     }
 
     #[inline]
-    fn starts_with(&self, needle: &[T]) -> bool {
+    fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
         let n = needle.len();
         self.len() >= n && needle == self[..n]
     }
 
     #[inline]
-    fn ends_with(&self, needle: &[T]) -> bool {
+    fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
         let (m, n) = (self.len(), needle.len());
         m >= n && needle == self[m-n..]
     }
-}
 
-/// Extension methods for slices containing `Ord` elements.
-#[unstable = "may merge with other traits"]
-#[allow(missing_docs)] // docs in libcollections
-pub trait OrdSliceExt<T: Ord> for Sized? {
-    fn binary_search(&self, x: &T) -> Result<uint, uint>;
-    fn next_permutation(&mut self) -> bool;
-    fn prev_permutation(&mut self) -> bool;
-}
-
-#[unstable = "trait is unstable"]
-impl<T: Ord> OrdSliceExt<T> for [T] {
     #[unstable]
-    fn binary_search(&self, x: &T) -> Result<uint, uint> {
+    fn binary_search(&self, x: &T) -> Result<uint, uint> where T: Ord {
         self.binary_search_by(|p| p.cmp(x))
     }
 
     #[experimental]
-    fn next_permutation(&mut self) -> bool {
+    fn next_permutation(&mut self) -> bool where T: Ord {
         // These cases only have 1 permutation each, so we can't do anything.
         if self.len() < 2 { return false; }
 
@@ -581,7 +489,7 @@ impl<T: Ord> OrdSliceExt<T> for [T] {
     }
 
     #[experimental]
-    fn prev_permutation(&mut self) -> bool {
+    fn prev_permutation(&mut self) -> bool where T: Ord {
         // These cases only have 1 permutation each, so we can't do anything.
         if self.len() < 2 { return false; }
 
@@ -610,19 +518,9 @@ impl<T: Ord> OrdSliceExt<T> for [T] {
 
         true
     }
-}
 
-/// Extension methods for slices on Clone elements
-#[unstable = "may merge with other traits"]
-#[allow(missing_docs)] // docs in libcollections
-pub trait CloneSliceExt<T> for Sized? {
-    fn clone_from_slice(&mut self, &[T]) -> uint;
-}
-
-#[unstable = "trait is unstable"]
-impl<T: Clone> CloneSliceExt<T> for [T] {
     #[inline]
-    fn clone_from_slice(&mut self, src: &[T]) -> uint {
+    fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone {
         let min = cmp::min(self.len(), src.len());
         let dst = self.slice_to_mut(min);
         let src = src.slice_to(min);
@@ -633,6 +531,79 @@ impl<T: Clone> CloneSliceExt<T> for [T] {
     }
 }
 
+impl<T> ops::Index<uint, T> for [T] {
+    fn index(&self, &index: &uint) -> &T {
+        assert!(index < self.len());
+
+        unsafe { mem::transmute(self.repr().data.offset(index as int)) }
+    }
+}
+
+impl<T> ops::IndexMut<uint, T> for [T] {
+    fn index_mut(&mut self, &index: &uint) -> &mut T {
+        assert!(index < self.len());
+
+        unsafe { mem::transmute(self.repr().data.offset(index as int)) }
+    }
+}
+
+impl<T> ops::Slice<uint, [T]> for [T] {
+    #[inline]
+    fn as_slice_<'a>(&'a self) -> &'a [T] {
+        self
+    }
+
+    #[inline]
+    fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
+        self.slice_or_fail(start, &self.len())
+    }
+
+    #[inline]
+    fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
+        self.slice_or_fail(&0, end)
+    }
+    #[inline]
+    fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
+        assert!(*start <= *end);
+        assert!(*end <= self.len());
+        unsafe {
+            transmute(RawSlice {
+                    data: self.as_ptr().offset(*start as int),
+                    len: (*end - *start)
+                })
+        }
+    }
+}
+
+impl<T> ops::SliceMut<uint, [T]> for [T] {
+    #[inline]
+    fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
+        self
+    }
+
+    #[inline]
+    fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
+        let len = &self.len();
+        self.slice_or_fail_mut(start, len)
+    }
+
+    #[inline]
+    fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
+        self.slice_or_fail_mut(&0, end)
+    }
+    #[inline]
+    fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
+        assert!(*start <= *end);
+        assert!(*end <= self.len());
+        unsafe {
+            transmute(RawSlice {
+                    data: self.as_ptr().offset(*start as int),
+                    len: (*end - *start)
+                })
+        }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Common traits
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
index 576989fabe7..ad2323296d9 100644
--- a/src/libcore/tuple.rs
+++ b/src/libcore/tuple.rs
@@ -32,35 +32,6 @@
 //! * `PartialOrd`
 //! * `Ord`
 //! * `Default`
-//!
-//! # Examples
-//!
-//! Using methods:
-//!
-//! ```
-//! #[allow(deprecated)]
-//! # fn main() {
-//! let pair = ("pi", 3.14f64);
-//! assert_eq!(pair.val0(), "pi");
-//! assert_eq!(pair.val1(), 3.14f64);
-//! # }
-//! ```
-//!
-//! Using traits implemented for tuples:
-//!
-//! ```
-//! use std::default::Default;
-//!
-//! let a = (1i, 2i);
-//! let b = (3i, 4i);
-//! assert!(a != b);
-//!
-//! let c = b.clone();
-//! assert!(b == c);
-//!
-//! let d : (u32, f32) = Default::default();
-//! assert_eq!(d, (0u32, 0.0f32));
-//! ```
 
 #![stable]
 
diff --git a/src/libcoretest/atomic.rs b/src/libcoretest/atomic.rs
index 1fee304a976..f8e943ec9f6 100644
--- a/src/libcoretest/atomic.rs
+++ b/src/libcoretest/atomic.rs
@@ -70,9 +70,9 @@ fn int_xor() {
     assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
 }
 
-static S_BOOL : AtomicBool = INIT_ATOMIC_BOOL;
-static S_INT  : AtomicInt  = INIT_ATOMIC_INT;
-static S_UINT : AtomicUint = INIT_ATOMIC_UINT;
+static S_BOOL : AtomicBool = ATOMIC_BOOL_INIT;
+static S_INT  : AtomicInt  = ATOMIC_INT_INIT;
+static S_UINT : AtomicUint = ATOMIC_UINT_INIT;
 
 #[test]
 fn static_init() {
diff --git a/src/libcoretest/cmp.rs b/src/libcoretest/cmp.rs
index 716300f652d..992c99f1f9f 100644
--- a/src/libcoretest/cmp.rs
+++ b/src/libcoretest/cmp.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::cmp::{ partial_min, partial_max };
+use core::cmp::{partial_min, partial_max};
+use core::cmp::Ordering::{Less, Greater, Equal};
 
 #[test]
 fn test_int_totalord() {
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index d450e557383..7952c96a117 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -10,6 +10,7 @@
 
 use core::iter::*;
 use core::iter::order::*;
+use core::iter::MinMaxResult::*;
 use core::num::SignedInt;
 use core::uint;
 use core::cmp;
diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs
index 55e0f10c865..e409dc61510 100644
--- a/src/libcoretest/num/int_macros.rs
+++ b/src/libcoretest/num/int_macros.rs
@@ -17,6 +17,7 @@ mod tests {
     use core::int;
     use core::num::{FromStrRadix, Int, SignedInt};
     use core::str::from_str;
+    use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
     use num;
 
     #[test]
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
index acc593d7be9..82e91c5b712 100644
--- a/src/libcoretest/num/mod.rs
+++ b/src/libcoretest/num/mod.rs
@@ -13,6 +13,7 @@ use core::fmt::Show;
 use core::num::{NumCast, cast};
 use core::ops::{Add, Sub, Mul, Div, Rem};
 use core::kinds::Copy;
+use std::str::from_str;
 
 mod int_macros;
 mod i8;
@@ -54,6 +55,7 @@ mod test {
     use core::option::Option::{Some, None};
     use core::num::Float;
     use core::num::from_str_radix;
+    use core::str::from_str;
 
     #[test]
     fn from_str_issue7588() {
diff --git a/src/libcoretest/num/uint_macros.rs b/src/libcoretest/num/uint_macros.rs
index b21ac11e6a0..2311c19d557 100644
--- a/src/libcoretest/num/uint_macros.rs
+++ b/src/libcoretest/num/uint_macros.rs
@@ -16,6 +16,7 @@ mod tests {
     use core::$T_i::*;
     use core::num::Int;
     use num;
+    use core::ops::{BitOr, BitAnd, BitXor, Shl, Shr, Not};
 
     #[test]
     fn test_overflows() {
diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs
index 63d6e14a4a6..fc02f46724f 100644
--- a/src/libcoretest/str.rs
+++ b/src/libcoretest/str.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::str::from_str;
+
 #[test]
 fn test_bool_from_str() {
     assert_eq!(from_str::<bool>("true"), Some(true));
diff --git a/src/libcoretest/tuple.rs b/src/libcoretest/tuple.rs
index f7b714757f8..c3bc38a6614 100644
--- a/src/libcoretest/tuple.rs
+++ b/src/libcoretest/tuple.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::cmp::Ordering::{Equal, Less, Greater};
+
 #[test]
 fn test_clone() {
     let a = (1i, "2");
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 7dd0649e483..01e55fb2edd 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -47,6 +47,7 @@
 //! which is cyclic.
 //!
 //! ```rust
+//! use std::borrow::IntoCow;
 //! use graphviz as dot;
 //!
 //! type Nd = int;
@@ -146,6 +147,7 @@
 //! entity `&sube`).
 //!
 //! ```rust
+//! use std::borrow::IntoCow;
 //! use graphviz as dot;
 //!
 //! type Nd = uint;
@@ -201,6 +203,7 @@
 //! Hasse-diagram for the subsets of the set `{x, y}`.
 //!
 //! ```rust
+//! use std::borrow::IntoCow;
 //! use graphviz as dot;
 //!
 //! type Nd<'a> = (uint, &'a str);
@@ -273,6 +276,7 @@
 
 pub use self::LabelText::*;
 
+use std::borrow::IntoCow;
 use std::io;
 use std::str::CowString;
 use std::vec::CowVec;
@@ -586,6 +590,7 @@ mod tests {
     use super::{Nodes, Edges, GraphWalk, render};
     use std::io::IoResult;
     use std::str;
+    use std::borrow::IntoCow;
 
     /// each node is an index in a vector in the graph.
     type Node = uint;
diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs
index ddda2b38c22..d0396ddc7ad 100644
--- a/src/libgraphviz/maybe_owned_vec.rs
+++ b/src/libgraphviz/maybe_owned_vec.rs
@@ -12,8 +12,10 @@
 
 pub use self::MaybeOwnedVector::*;
 
+use std::cmp::{Equiv, Ordering};
 use std::default::Default;
 use std::fmt;
+use std::iter::FromIterator;
 use std::path::BytesContainer;
 use std::slice;
 
@@ -96,9 +98,9 @@ impl<'a, T: Ord> Ord for MaybeOwnedVector<'a, T> {
 }
 
 #[allow(deprecated)]
-impl<'a, T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
-    fn equiv(&self, other: &V) -> bool {
-        self.as_slice() == other.as_slice()
+impl<'a, T: PartialEq> Equiv<[T]> for MaybeOwnedVector<'a, T> {
+    fn equiv(&self, other: &[T]) -> bool {
+        self.as_slice() == other
     }
 }
 
@@ -125,7 +127,7 @@ impl<'a,T> FromIterator<T> for MaybeOwnedVector<'a,T> {
     fn from_iter<I:Iterator<T>>(iterator: I) -> MaybeOwnedVector<'a,T> {
         // If we are building from scratch, might as well build the
         // most flexible variant.
-        Growable(FromIterator::from_iter(iterator))
+        Growable(iterator.collect())
     }
 }
 
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index b30938ae7f5..4ee5b2d5e83 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -352,7 +352,7 @@ pub struct LogLocation {
 #[doc(hidden)]
 pub fn mod_enabled(level: u32, module: &str) -> bool {
     static INIT: Once = ONCE_INIT;
-    INIT.doit(init);
+    INIT.call_once(init);
 
     // It's possible for many threads are in this function, only one of them
     // will perform the global initialization, but all of them will need to check
diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs
index 49577cd279b..8e6c7de305f 100644
--- a/src/librand/chacha.rs
+++ b/src/librand/chacha.rs
@@ -206,7 +206,7 @@ impl Rand for ChaChaRng {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use core::iter::order;
     use {Rng, SeedableRng};
diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs
index f31f3468a4c..981b0eeee53 100644
--- a/src/librand/distributions/exponential.rs
+++ b/src/librand/distributions/exponential.rs
@@ -94,7 +94,7 @@ impl IndependentSample<f64> for Exp {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use distributions::{Sample, IndependentSample};
     use super::Exp;
@@ -124,7 +124,7 @@ mod test {
 mod bench {
     extern crate test;
 
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use self::test::Bencher;
     use std::mem::size_of;
diff --git a/src/librand/distributions/gamma.rs b/src/librand/distributions/gamma.rs
index 618db380db8..378029d1f9b 100644
--- a/src/librand/distributions/gamma.rs
+++ b/src/librand/distributions/gamma.rs
@@ -323,7 +323,7 @@ impl IndependentSample<f64> for StudentT {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use distributions::{Sample, IndependentSample};
     use super::{ChiSquared, StudentT, FisherF};
@@ -385,7 +385,7 @@ mod test {
 #[cfg(test)]
 mod bench {
     extern crate test;
-    use std::prelude::*;
+    use std::prelude::v1::*;
     use self::test::Bencher;
     use std::mem::size_of;
     use distributions::IndependentSample;
diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
index 54cb8ae1907..d0123d9c76c 100644
--- a/src/librand/distributions/mod.rs
+++ b/src/librand/distributions/mod.rs
@@ -258,7 +258,7 @@ fn ziggurat<R: Rng, P, Z>(
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use {Rng, Rand};
     use super::{RandSample, WeightedChoice, Weighted, Sample, IndependentSample};
diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs
index 3507282ec48..543e236f96d 100644
--- a/src/librand/distributions/normal.rs
+++ b/src/librand/distributions/normal.rs
@@ -160,7 +160,7 @@ impl IndependentSample<f64> for LogNormal {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use distributions::{Sample, IndependentSample};
     use super::{Normal, LogNormal};
@@ -200,7 +200,7 @@ mod tests {
 #[cfg(test)]
 mod bench {
     extern crate test;
-    use std::prelude::*;
+    use std::prelude::v1::*;
     use self::test::Bencher;
     use std::mem::size_of;
     use distributions::{Sample};
diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs
index 20ba3566d5b..558fa201256 100644
--- a/src/librand/distributions/range.rs
+++ b/src/librand/distributions/range.rs
@@ -164,7 +164,7 @@ float_impl! { f64 }
 #[cfg(test)]
 mod tests {
     use std::num::Int;
-    use std::prelude::*;
+    use std::prelude::v1::*;
     use distributions::{Sample, IndependentSample};
     use super::Range;
 
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index 1fe435a59ad..1ea47844075 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -487,7 +487,7 @@ impl Rand for Isaac64Rng {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use core::iter::order;
     use {Rng, SeedableRng};
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index 568d2459118..bbcd99afdea 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -52,14 +52,14 @@ pub mod reseeding;
 mod rand_impls;
 
 /// A type that can be randomly generated using an `Rng`.
-pub trait Rand {
+pub trait Rand : Sized {
     /// Generates a random instance of this type using the specified source of
     /// randomness.
     fn rand<R: Rng>(rng: &mut R) -> Self;
 }
 
 /// A random number generator.
-pub trait Rng {
+pub trait Rng : Sized {
     /// Return the next random u32.
     ///
     /// This rarely needs to be called directly, prefer `r.gen()` to
diff --git a/src/librand/rand_impls.rs b/src/librand/rand_impls.rs
index e50153076c3..c331807c1b9 100644
--- a/src/librand/rand_impls.rs
+++ b/src/librand/rand_impls.rs
@@ -214,7 +214,7 @@ impl<T:Rand> Rand for Option<T> {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::*;
+    use std::prelude::v1::*;
     use std::rand::{Rng, thread_rng, Open01, Closed01};
 
     struct ConstantRng(u64);
diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs
index 94a11c040e4..46371d427e6 100644
--- a/src/librand/reseeding.rs
+++ b/src/librand/reseeding.rs
@@ -149,7 +149,7 @@ impl Default for ReseedWithDefault {
 
 #[cfg(test)]
 mod test {
-    use std::prelude::*;
+    use std::prelude::v1::*;
 
     use core::iter::order;
     use super::{ReseedingRng, ReseedWithDefault};
diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index 51c23463155..3171966a596 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -11,6 +11,7 @@
 pub use self::NamesIter::*;
 pub use self::Regex::*;
 
+use std::borrow::IntoCow;
 use std::collections::HashMap;
 use std::fmt;
 use std::str::CowString;
diff --git a/src/libregex/vm.rs b/src/libregex/vm.rs
index 72e0e559c80..603ca57d15d 100644
--- a/src/libregex/vm.rs
+++ b/src/libregex/vm.rs
@@ -37,6 +37,7 @@ pub use self::MatchKind::*;
 pub use self::StepState::*;
 
 use std::cmp;
+use std::cmp::Ordering::{mod, Less, Equal, Greater};
 use std::mem;
 use std::iter::repeat;
 use std::slice::SliceExt;
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 4647c92e3d1..cdc27244dde 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -22,10 +22,12 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
+#![allow(unknown_features)]
 #![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
 
 extern crate arena;
 extern crate flate;
@@ -98,6 +100,7 @@ pub mod middle {
     pub mod traits;
     pub mod ty;
     pub mod ty_fold;
+    pub mod ty_walk;
     pub mod weak_lang_items;
 }
 
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 82aa40cb0ad..c314fba91d5 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -36,10 +36,11 @@ use util::ppaux::{ty_to_string};
 use util::nodemap::{FnvHashMap, NodeSet};
 use lint::{Context, LintPass, LintArray};
 
-use std::{cmp, slice};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::num::SignedInt;
+use std::{cmp, slice};
 use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
+
 use syntax::{abi, ast, ast_map};
 use syntax::ast_util::is_shift_binop;
 use syntax::attr::{mod, AttrMetaMethods};
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index d079d0e52aa..a25b6d8b8fa 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -32,13 +32,15 @@ use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty::{mod, Ty};
 use middle::astencode::vtable_decoder_helpers;
 
+use std::collections::HashMap;
 use std::hash::Hash;
 use std::hash;
 use std::io::extensions::u64_from_be_bytes;
 use std::io;
-use std::collections::hash_map::HashMap;
+use std::num::FromPrimitive;
 use std::rc::Rc;
 use std::str;
+
 use rbml::reader;
 use rbml;
 use serialize::Decodable;
@@ -441,9 +443,15 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
                             -> Option<Rc<ty::TraitRef<'tcx>>>
 {
     let item_doc = lookup_item(id, cdata.data());
-    reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
-        doc_trait_ref(tp, tcx, cdata)
-    })
+    let fam = item_family(item_doc);
+    match fam {
+        Family::Impl => {
+            reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
+                doc_trait_ref(tp, tcx, cdata)
+            })
+        }
+        _ => None
+    }
 }
 
 pub fn get_impl_vtables<'tcx>(cdata: Cmd,
@@ -1273,9 +1281,9 @@ pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
 }
 
 pub fn each_implementation_for_type<F>(cdata: Cmd,
-                                    id: ast::NodeId,
-                                    mut callback: F) where
-    F: FnMut(ast::DefId),
+                                       id: ast::NodeId,
+                                       mut callback: F)
+    where F: FnMut(ast::DefId),
 {
     let item_doc = lookup_item(id, cdata.data());
     reader::tagged_docs(item_doc,
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 8378c620c1d..10383b901f3 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1222,8 +1222,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_attributes(rbml_w, item.attrs[]);
         encode_unsafety(rbml_w, unsafety);
         match ty.node {
-            ast::TyPath(ref path, _) if path.segments
-                                                        .len() == 1 => {
+            ast::TyPath(ref path, _) if path.segments.len() == 1 => {
                 let ident = path.segments.last().unwrap().identifier;
                 encode_impl_type_basename(rbml_w, ident);
             }
@@ -1351,6 +1350,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
         // Encode the implementations of this trait.
         encode_extension_implementations(ecx, rbml_w, def_id);
 
+        // Encode inherent implementations for this trait.
+        encode_inherent_implementations(ecx, rbml_w, def_id);
+
         rbml_w.end_tag();
 
         // Now output the trait item info for each trait item.
@@ -1453,9 +1455,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
             rbml_w.end_tag();
         }
-
-        // Encode inherent implementations for this trait.
-        encode_inherent_implementations(ecx, rbml_w, def_id);
       }
       ast::ItemMac(..) => {
         // macros are encoded separately
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 88c7ccf1b1e..2d3ff95ffa6 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -25,7 +25,6 @@ use middle::ty::{mod, AsPredicate, Ty};
 
 use std::rc::Rc;
 use std::str;
-use std::string::String;
 use syntax::abi;
 use syntax::ast;
 use syntax::parse::token;
diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs
index 13bd22a67c4..06fef66c1e0 100644
--- a/src/librustc/middle/cfg/graphviz.rs
+++ b/src/librustc/middle/cfg/graphviz.rs
@@ -11,7 +11,9 @@
 /// This module provides linkage between rustc::middle::graph and
 /// libgraphviz traits.
 
-/// For clarity, rename the graphviz crate locally to dot.
+use std::borrow::IntoCow;
+
+// For clarity, rename the graphviz crate locally to dot.
 use graphviz as dot;
 
 use syntax::ast;
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 4c5d76a2c40..d16224ec5b8 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -24,8 +24,7 @@ use middle::pat_util::*;
 use middle::ty::*;
 use middle::ty;
 use std::fmt;
-use std::iter::AdditiveIterator;
-use std::iter::{range_inclusive, repeat};
+use std::iter::{range_inclusive, AdditiveIterator, FromIterator, repeat};
 use std::num::Float;
 use std::slice;
 use syntax::ast::{mod, DUMMY_NODE_ID, NodeId, Pat};
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 5b89912dd03..9fc5cb03353 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -27,8 +27,8 @@ use syntax::ptr::P;
 use syntax::visit::{mod, Visitor};
 use syntax::{ast_map, ast_util, codemap};
 
-use std::rc::Rc;
 use std::collections::hash_map::Entry::Vacant;
+use std::rc::Rc;
 
 //
 // This pass classifies expressions by their constant-ness.
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index e0bcdfc6d8d..ab6f6b601f6 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -57,7 +57,7 @@ use syntax::ast;
 use syntax::abi;
 use syntax::codemap::Span;
 
-pub trait Combine<'tcx> {
+pub trait Combine<'tcx> : Sized {
     fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx>;
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.infcx().tcx }
     fn tag(&self) -> String;
diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs
index 8455ee3955b..b6020fe5ce3 100644
--- a/src/librustc/middle/infer/region_inference/graphviz.rs
+++ b/src/librustc/middle/infer/region_inference/graphviz.rs
@@ -73,7 +73,7 @@ pub fn maybe_print_constraints_for<'a, 'tcx>(region_vars: &RegionVarBindings<'a,
     let output_path = {
         let output_template = match requested_output {
             Some(ref s) if s.as_slice() == "help" => {
-                static PRINTED_YET : atomic::AtomicBool = atomic::INIT_ATOMIC_BOOL;
+                static PRINTED_YET : atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT;
                 if !PRINTED_YET.load(atomic::SeqCst) {
                     print_help_message();
                     PRINTED_YET.store(true, atomic::SeqCst);
diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index 7372bb267b0..6ac1c5470cc 100644
--- a/src/librustc/middle/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -33,8 +33,9 @@ use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux::Repr;
 
 use std::cell::{Cell, RefCell};
-use std::u32;
+use std::cmp::Ordering::{mod, Less, Greater, Equal};
 use std::iter::repeat;
+use std::u32;
 use syntax::ast;
 
 mod doc;
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 2aef4307199..78fabcd588a 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -36,6 +36,7 @@ use syntax::visit::Visitor;
 use syntax::visit;
 
 use std::iter::Enumerate;
+use std::num::FromPrimitive;
 use std::slice;
 
 // The actual lang items defined come at the end of this file in one handy table.
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index be89b32cdaa..0e47f338bb9 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -649,7 +649,10 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
         Some(ref expr) => {
             record_rvalue_scope_if_borrow_expr(visitor, &**expr, blk_scope);
 
-            if is_binding_pat(&*local.pat) || is_borrowed_ty(&*local.ty) {
+            let is_borrow =
+                if let Some(ref ty) = local.ty { is_borrowed_ty(&**ty) } else { false };
+
+            if is_binding_pat(&*local.pat) || is_borrow {
                 record_rvalue_scope(visitor, &**expr, blk_scope);
             }
         }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index d793f49efe5..505352fa123 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -11,7 +11,8 @@
 //! A pass that annotates every item and method with its stability level,
 //! propagating default levels lexically from parent to children ast nodes.
 
-use util::nodemap::{NodeMap, DefIdMap};
+use middle::ty;
+use metadata::csearch;
 use syntax::codemap::Span;
 use syntax::{attr, visit};
 use syntax::ast;
@@ -21,8 +22,8 @@ use syntax::ast::{TypeMethod, Method, Generics, StructField, TypeTraitItem};
 use syntax::ast_util::is_local;
 use syntax::attr::Stability;
 use syntax::visit::{FnKind, FkMethod, Visitor};
-use middle::ty;
-use metadata::csearch;
+use util::nodemap::{NodeMap, DefIdMap};
+use util::ppaux::Repr;
 
 use std::mem::replace;
 
@@ -154,10 +155,13 @@ impl Index {
 /// Lookup the stability for a node, loading external crate
 /// metadata as necessary.
 pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
+    debug!("lookup(id={})",
+           id.repr(tcx));
+
     // is this definition the implementation of a trait method?
     match ty::trait_item_of_item(tcx, id) {
-        Some(ty::MethodTraitItemId(trait_method_id))
-                if trait_method_id != id => {
+        Some(ty::MethodTraitItemId(trait_method_id)) if trait_method_id != id => {
+            debug!("lookup: trait_method_id={}", trait_method_id);
             return lookup(tcx, trait_method_id)
         }
         _ => {}
@@ -178,6 +182,7 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
             // stability of the trait to determine the stability of any
             // unmarked impls for it. See FIXME above for more details.
 
+            debug!("lookup: trait_id={}", trait_id);
             lookup(tcx, trait_id)
         } else {
             None
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 3c5459ff3bc..97e74b9f6bb 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -519,7 +519,7 @@ impl<'a,T> Iterator<(ParamSpace, uint, &'a T)> for EnumeratedItems<'a,T> {
 // `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
 // there is more information available (for better errors).
 
-pub trait Subst<'tcx> {
+pub trait Subst<'tcx> : Sized {
     fn subst(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>) -> Self {
         self.subst_spanned(tcx, substs, None)
     }
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index d8b39d92c69..4aff36c2624 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -14,10 +14,10 @@ use super::SelectionContext;
 use super::{Obligation, ObligationCause};
 use super::util;
 
-use middle::subst;
 use middle::subst::Subst;
 use middle::ty::{mod, Ty};
 use middle::infer::InferCtxt;
+use std::collections::HashSet;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::DUMMY_SP;
@@ -52,9 +52,21 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
     selcx.evaluate_impl(impl2_def_id, &obligation)
 }
 
-pub fn impl_is_local(tcx: &ty::ctxt,
-                     impl_def_id: ast::DefId)
-                     -> bool
+#[allow(missing_copy_implementations)]
+pub enum OrphanCheckErr {
+    NoLocalInputType,
+    UncoveredTypeParameter(ty::ParamTy),
+}
+
+/// Checks the coherence orphan rules. `impl_def_id` should be the
+/// def-id of a trait impl. To pass, either the trait must be local, or else
+/// two conditions must be satisfied:
+///
+/// 1. At least one of the input types must involve a local type.
+/// 2. All type parameters must be covered by a local type.
+pub fn orphan_check(tcx: &ty::ctxt,
+                    impl_def_id: ast::DefId)
+                    -> Result<(), OrphanCheckErr>
 {
     debug!("impl_is_local({})", impl_def_id.repr(tcx));
 
@@ -63,20 +75,40 @@ pub fn impl_is_local(tcx: &ty::ctxt,
     let trait_ref = ty::impl_trait_ref(tcx, impl_def_id).unwrap();
     debug!("trait_ref={}", trait_ref.repr(tcx));
 
-    // If the trait is local to the crate, ok.
+    // If the *trait* is local to the crate, ok.
     if trait_ref.def_id.krate == ast::LOCAL_CRATE {
         debug!("trait {} is local to current crate",
                trait_ref.def_id.repr(tcx));
-        return true;
+        return Ok(());
     }
 
-    // Otherwise, at least one of the input types must be local to the
-    // crate.
-    trait_ref.input_types().iter().any(|&t| ty_is_local(tcx, t))
+    // Check condition 1: at least one type must be local.
+    if !trait_ref.input_types().iter().any(|&t| ty_reaches_local(tcx, t)) {
+        return Err(OrphanCheckErr::NoLocalInputType);
+    }
+
+    // Check condition 2: type parameters must be "covered" by a local type.
+    let covered_params: HashSet<_> =
+        trait_ref.input_types().iter()
+                               .flat_map(|&t| type_parameters_covered_by_ty(tcx, t).into_iter())
+                               .collect();
+    let all_params: HashSet<_> =
+        trait_ref.input_types().iter()
+                               .flat_map(|&t| type_parameters_reachable_from_ty(t).into_iter())
+                               .collect();
+    for &param in all_params.difference(&covered_params) {
+        return Err(OrphanCheckErr::UncoveredTypeParameter(param));
+    }
+
+    return Ok(());
+}
+
+fn ty_reaches_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
+    ty.walk().any(|t| ty_is_local_constructor(tcx, t))
 }
 
-pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    debug!("ty_is_local({})", ty.repr(tcx));
+fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
+    debug!("ty_is_local_constructor({})", ty.repr(tcx));
 
     match ty.sty {
         ty::ty_bool |
@@ -84,78 +116,33 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
         ty::ty_int(..) |
         ty::ty_uint(..) |
         ty::ty_float(..) |
-        ty::ty_str(..) => {
-            false
-        }
-
-        ty::ty_unboxed_closure(..) => {
-            // This routine is invoked on types specified by users as
-            // part of an impl and hence an unboxed closure type
-            // cannot appear.
-            tcx.sess.bug("ty_is_local applied to unboxed closure type")
-        }
-
+        ty::ty_str(..) |
         ty::ty_bare_fn(..) |
-        ty::ty_closure(..) => {
+        ty::ty_closure(..) |
+        ty::ty_vec(..) |
+        ty::ty_ptr(..) |
+        ty::ty_rptr(..) |
+        ty::ty_tup(..) |
+        ty::ty_param(..) |
+        ty::ty_projection(..) => {
             false
         }
 
-        ty::ty_uniq(t) => {
-            let krate = tcx.lang_items.owned_box().map(|d| d.krate);
-            krate == Some(ast::LOCAL_CRATE) || ty_is_local(tcx, t)
-        }
-
-        ty::ty_vec(t, _) |
-        ty::ty_ptr(ty::mt { ty: t, .. }) |
-        ty::ty_rptr(_, ty::mt { ty: t, .. }) => {
-            ty_is_local(tcx, t)
-        }
-
-        ty::ty_tup(ref ts) => {
-            ts.iter().any(|&t| ty_is_local(tcx, t))
+        ty::ty_enum(def_id, _) |
+        ty::ty_struct(def_id, _) => {
+            def_id.krate == ast::LOCAL_CRATE
         }
 
-        ty::ty_enum(def_id, ref substs) |
-        ty::ty_struct(def_id, ref substs) => {
-            def_id.krate == ast::LOCAL_CRATE || {
-                let variances = ty::item_variances(tcx, def_id);
-                subst::ParamSpace::all().iter().any(|&space| {
-                    substs.types.get_slice(space).iter().enumerate().any(
-                        |(i, &t)| {
-                            match *variances.types.get(space, i) {
-                                ty::Bivariant => {
-                                    // If Foo<T> is bivariant with respect to
-                                    // T, then it doesn't matter whether T is
-                                    // local or not, because `Foo<U>` for any
-                                    // U will be a subtype of T.
-                                    false
-                                }
-                                ty::Contravariant |
-                                ty::Covariant |
-                                ty::Invariant => {
-                                    ty_is_local(tcx, t)
-                                }
-                            }
-                        })
-                })
-            }
+        ty::ty_uniq(_) => { // treat ~T like Box<T>
+            let krate = tcx.lang_items.owned_box().map(|d| d.krate);
+            krate == Some(ast::LOCAL_CRATE)
         }
 
         ty::ty_trait(ref tt) => {
             tt.principal_def_id().krate == ast::LOCAL_CRATE
         }
 
-        // Type parameters may be bound to types that are not local to
-        // the crate.
-        ty::ty_param(..) => {
-            false
-        }
-
-        // Associated types could be anything, I guess.
-        ty::ty_projection(..) => {
-            false
-        }
-
+        ty::ty_unboxed_closure(..) |
         ty::ty_infer(..) |
         ty::ty_open(..) |
         ty::ty_err => {
@@ -165,3 +152,27 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
         }
     }
 }
+
+fn type_parameters_covered_by_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                 ty: Ty<'tcx>)
+                                 -> HashSet<ty::ParamTy>
+{
+    if ty_is_local_constructor(tcx, ty) {
+        type_parameters_reachable_from_ty(ty)
+    } else {
+        ty.walk_children().flat_map(|t| type_parameters_covered_by_ty(tcx, t).into_iter()).collect()
+    }
+}
+
+/// All type parameters reachable from `ty`
+fn type_parameters_reachable_from_ty<'tcx>(ty: Ty<'tcx>) -> HashSet<ty::ParamTy> {
+    ty.walk()
+        .filter_map(|t| {
+            match t.sty {
+                ty::ty_param(ref param_ty) => Some(param_ty.clone()),
+                _ => None,
+            }
+        })
+        .collect()
+}
+
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index b10dfa5b718..c83898bcd8a 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -25,24 +25,33 @@ use syntax::codemap::{Span, DUMMY_SP};
 use util::ppaux::Repr;
 
 pub use self::error_reporting::report_fulfillment_errors;
+pub use self::coherence::orphan_check;
+pub use self::coherence::OrphanCheckErr;
 pub use self::fulfill::{FulfillmentContext, RegionObligation};
 pub use self::project::MismatchedProjectionTypes;
 pub use self::project::normalize;
 pub use self::project::Normalized;
+pub use self::object_safety::is_object_safe;
+pub use self::object_safety::object_safety_violations;
+pub use self::object_safety::ObjectSafetyViolation;
+pub use self::object_safety::MethodViolationCode;
 pub use self::select::SelectionContext;
 pub use self::select::SelectionCache;
 pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
 pub use self::select::{MethodMatchedData}; // intentionally don't export variants
 pub use self::util::elaborate_predicates;
+pub use self::util::get_vtable_index_of_object_method;
 pub use self::util::trait_ref_for_builtin_bound;
 pub use self::util::supertraits;
 pub use self::util::Supertraits;
 pub use self::util::transitive_bounds;
+pub use self::util::upcast;
 
 mod coherence;
 mod error_reporting;
 mod fulfill;
 mod project;
+mod object_safety;
 mod select;
 mod util;
 
@@ -210,6 +219,9 @@ pub enum Vtable<'tcx, N> {
     /// for some type parameter.
     VtableParam,
 
+    /// Virtual calls through an object
+    VtableObject(VtableObjectData<'tcx>),
+
     /// Successful resolution for a builtin trait.
     VtableBuiltin(VtableBuiltinData<N>),
 
@@ -245,13 +257,11 @@ pub struct VtableBuiltinData<N> {
     pub nested: subst::VecPerParamSpace<N>
 }
 
-/// True if neither the trait nor self type is local. Note that `impl_def_id` must refer to an impl
-/// of a trait, not an inherent impl.
-pub fn is_orphan_impl(tcx: &ty::ctxt,
-                      impl_def_id: ast::DefId)
-                      -> bool
-{
-    !coherence::impl_is_local(tcx, impl_def_id)
+/// A vtable for some object-safe trait `Foo` automatically derived
+/// for the object type `Foo`.
+#[deriving(PartialEq,Eq,Clone)]
+pub struct VtableObjectData<'tcx> {
+    pub object_ty: Ty<'tcx>,
 }
 
 /// True if there exist types that satisfy both of the two given impls.
@@ -365,6 +375,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             VtableFnPointer(..) => (&[]).iter(),
             VtableUnboxedClosure(..) => (&[]).iter(),
             VtableParam => (&[]).iter(),
+            VtableObject(_) => (&[]).iter(),
             VtableBuiltin(ref i) => i.iter_nested(),
         }
     }
@@ -375,6 +386,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
             VtableUnboxedClosure(d, ref s) => VtableUnboxedClosure(d, s.clone()),
             VtableParam => VtableParam,
+            VtableObject(ref p) => VtableObject(p.clone()),
             VtableBuiltin(ref b) => VtableBuiltin(b.map_nested(op)),
         }
     }
@@ -387,6 +399,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             VtableFnPointer(sig) => VtableFnPointer(sig),
             VtableUnboxedClosure(d, s) => VtableUnboxedClosure(d, s),
             VtableParam => VtableParam,
+            VtableObject(p) => VtableObject(p),
             VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
         }
     }
diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs
new file mode 100644
index 00000000000..6b7bf82af92
--- /dev/null
+++ b/src/librustc/middle/traits/object_safety.rs
@@ -0,0 +1,301 @@
+// 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.
+
+//! "Object safety" refers to the ability for a trait to be converted
+//! to an object. In general, traits may only be converted to an
+//! object if all of their methods meet certain criteria. In particular,
+//! they must:
+//!
+//!   - have a suitable receiver from which we can extract a vtable;
+//!   - not reference the erased type `Self` except for in this receiver;
+//!   - not have generic type parameters
+
+use super::supertraits;
+use super::elaborate_predicates;
+
+use middle::subst::{mod, SelfSpace};
+use middle::traits;
+use middle::ty::{mod, Ty};
+use std::rc::Rc;
+use syntax::ast;
+use util::ppaux::Repr;
+
+pub enum ObjectSafetyViolation<'tcx> {
+    /// Self : Sized declared on the trait
+    SizedSelf,
+
+    /// Method has someting illegal
+    Method(Rc<ty::Method<'tcx>>, MethodViolationCode),
+}
+
+/// Reasons a method might not be object-safe.
+#[deriving(Copy,Clone,Show)]
+pub enum MethodViolationCode {
+    /// e.g., `fn(self)`
+    ByValueSelf,
+
+    /// e.g., `fn foo()`
+    StaticMethod,
+
+    /// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
+    ReferencesSelf,
+
+    /// e.g., `fn foo<A>()`
+    Generic,
+}
+
+pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>,
+                            trait_ref: ty::PolyTraitRef<'tcx>)
+                            -> bool
+{
+    // Because we query yes/no results frequently, we keep a cache:
+    let cached_result =
+        tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).map(|&r| r);
+
+    let result =
+        cached_result.unwrap_or_else(|| {
+            let result = object_safety_violations(tcx, trait_ref.clone()).is_empty();
+
+            // Record just a yes/no result in the cache; this is what is
+            // queried most frequently. Note that this may overwrite a
+            // previous result, but always with the same thing.
+            tcx.object_safety_cache.borrow_mut().insert(trait_ref.def_id(), result);
+
+            result
+        });
+
+    debug!("is_object_safe({}) = {}", trait_ref.repr(tcx), result);
+
+    result
+}
+
+pub fn object_safety_violations<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                      sub_trait_ref: ty::PolyTraitRef<'tcx>)
+                                      -> Vec<ObjectSafetyViolation<'tcx>>
+{
+    supertraits(tcx, sub_trait_ref)
+        .flat_map(|tr| object_safety_violations_for_trait(tcx, tr.def_id()).into_iter())
+        .collect()
+}
+
+fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                            trait_def_id: ast::DefId)
+                                            -> Vec<ObjectSafetyViolation<'tcx>>
+{
+    // Check methods for violations.
+    let mut violations: Vec<_> =
+        ty::trait_items(tcx, trait_def_id).iter()
+        .flat_map(|item| {
+            match *item {
+                ty::MethodTraitItem(ref m) => {
+                    object_safety_violations_for_method(tcx, trait_def_id, &**m)
+                        .map(|code| ObjectSafetyViolation::Method(m.clone(), code))
+                        .into_iter()
+                }
+                ty::TypeTraitItem(_) => {
+                    None.into_iter()
+                }
+            }
+        })
+        .collect();
+
+    // Check the trait itself.
+    if trait_has_sized_self(tcx, trait_def_id) {
+        violations.push(ObjectSafetyViolation::SizedSelf);
+    }
+
+    debug!("object_safety_violations_for_trait(trait_def_id={}) = {}",
+           trait_def_id.repr(tcx),
+           violations.repr(tcx));
+
+    violations
+}
+
+fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
+                              trait_def_id: ast::DefId)
+                              -> bool
+{
+    let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
+    let param_env = ty::construct_parameter_environment(tcx,
+                                                        &trait_def.generics,
+                                                        ast::DUMMY_NODE_ID);
+    let predicates = param_env.caller_bounds.predicates.as_slice().to_vec();
+    let sized_def_id = match tcx.lang_items.sized_trait() {
+        Some(def_id) => def_id,
+        None => { return false; /* No Sized trait, can't require it! */ }
+    };
+
+    // Search for a predicate like `Self : Sized` amongst the trait bounds.
+    elaborate_predicates(tcx, predicates)
+        .any(|predicate| {
+            match predicate {
+                ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
+                    let self_ty = trait_pred.0.self_ty();
+                    match self_ty.sty {
+                        ty::ty_param(ref data) => data.space == subst::SelfSpace,
+                        _ => false,
+                    }
+                }
+                ty::Predicate::Projection(..) |
+                ty::Predicate::Trait(..) |
+                ty::Predicate::Equate(..) |
+                ty::Predicate::RegionOutlives(..) |
+                ty::Predicate::TypeOutlives(..) => {
+                    false
+                }
+            }
+        })
+}
+
+fn object_safety_violations_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                             trait_def_id: ast::DefId,
+                                             method: &ty::Method<'tcx>)
+                                             -> Option<MethodViolationCode>
+{
+    // The method's first parameter must be something that derefs to
+    // `&self`. For now, we only accept `&self` and `Box<Self>`.
+    match method.explicit_self {
+        ty::ByValueExplicitSelfCategory => {
+            return Some(MethodViolationCode::ByValueSelf);
+        }
+
+        ty::StaticExplicitSelfCategory => {
+            return Some(MethodViolationCode::StaticMethod);
+        }
+
+        ty::ByReferenceExplicitSelfCategory(..) |
+        ty::ByBoxExplicitSelfCategory => {
+        }
+    }
+
+    // The `Self` type is erased, so it should not appear in list of
+    // arguments or return type apart from the receiver.
+    let ref sig = method.fty.sig;
+    for &input_ty in sig.0.inputs[1..].iter() {
+        if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) {
+            return Some(MethodViolationCode::ReferencesSelf);
+        }
+    }
+    if let ty::FnConverging(result_type) = sig.0.output {
+        if contains_illegal_self_type_reference(tcx, trait_def_id, result_type) {
+            return Some(MethodViolationCode::ReferencesSelf);
+        }
+    }
+
+    // We can't monomorphize things like `fn foo<A>(...)`.
+    if !method.generics.types.is_empty_in(subst::FnSpace) {
+        return Some(MethodViolationCode::Generic);
+    }
+
+    None
+}
+
+fn contains_illegal_self_type_reference<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                              trait_def_id: ast::DefId,
+                                              ty: Ty<'tcx>)
+                                              -> bool
+{
+    // This is somewhat subtle. In general, we want to forbid
+    // references to `Self` in the argument and return types,
+    // since the value of `Self` is erased. However, there is one
+    // exception: it is ok to reference `Self` in order to access
+    // an associated type of the current trait, since we retain
+    // the value of those associated types in the object type
+    // itself.
+    //
+    // ```rust
+    // trait SuperTrait {
+    //     type X;
+    // }
+    //
+    // trait Trait : SuperTrait {
+    //     type Y;
+    //     fn foo(&self, x: Self) // bad
+    //     fn foo(&self) -> Self // bad
+    //     fn foo(&self) -> Option<Self> // bad
+    //     fn foo(&self) -> Self::Y // OK, desugars to next example
+    //     fn foo(&self) -> <Self as Trait>::Y // OK
+    //     fn foo(&self) -> Self::X // OK, desugars to next example
+    //     fn foo(&self) -> <Self as SuperTrait>::X // OK
+    // }
+    // ```
+    //
+    // However, it is not as simple as allowing `Self` in a projected
+    // type, because there are illegal ways to use `Self` as well:
+    //
+    // ```rust
+    // trait Trait : SuperTrait {
+    //     ...
+    //     fn foo(&self) -> <Self as SomeOtherTrait>::X;
+    // }
+    // ```
+    //
+    // Here we will not have the type of `X` recorded in the
+    // object type, and we cannot resolve `Self as SomeOtherTrait`
+    // without knowing what `Self` is.
+
+    let mut supertraits: Option<Vec<ty::PolyTraitRef<'tcx>>> = None;
+    let mut error = false;
+    ty::maybe_walk_ty(ty, |ty| {
+        match ty.sty {
+            ty::ty_param(ref param_ty) => {
+                if param_ty.space == SelfSpace {
+                    error = true;
+                }
+
+                false // no contained types to walk
+            }
+
+            ty::ty_projection(ref data) => {
+                // This is a projected type `<Foo as SomeTrait>::X`.
+
+                // Compute supertraits of current trait lazilly.
+                if supertraits.is_none() {
+                    let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
+                    let trait_ref = ty::Binder(trait_def.trait_ref.clone());
+                    supertraits = Some(traits::supertraits(tcx, trait_ref).collect());
+                }
+
+                // Determine whether the trait reference `Foo as
+                // SomeTrait` is in fact a supertrait of the
+                // current trait. In that case, this type is
+                // legal, because the type `X` will be specified
+                // in the object type.  Note that we can just use
+                // direct equality here because all of these types
+                // are part of the formal parameter listing, and
+                // hence there should be no inference variables.
+                let projection_trait_ref = ty::Binder(data.trait_ref.clone());
+                let is_supertrait_of_current_trait =
+                    supertraits.as_ref().unwrap().contains(&projection_trait_ref);
+
+                if is_supertrait_of_current_trait {
+                    false // do not walk contained types, do not report error, do collect $200
+                } else {
+                    true // DO walk contained types, POSSIBLY reporting an error
+                }
+            }
+
+            _ => true, // walk contained types, if any
+        }
+    });
+
+    error
+}
+
+impl<'tcx> Repr<'tcx> for ObjectSafetyViolation<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        match *self {
+            ObjectSafetyViolation::SizedSelf =>
+                format!("SizedSelf"),
+            ObjectSafetyViolation::Method(ref m, code) =>
+                format!("Method({},{})", m.repr(tcx), code),
+        }
+    }
+}
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs
index c84f31bf6c3..d7f570df072 100644
--- a/src/librustc/middle/traits/project.rs
+++ b/src/librustc/middle/traits/project.rs
@@ -21,8 +21,10 @@ use super::VtableImplData;
 
 use middle::infer;
 use middle::subst::Subst;
-use middle::ty::{mod, AsPredicate, RegionEscape, HasProjectionTypes, ToPolyTraitRef, Ty};
+use middle::ty::{mod, AsPredicate, ReferencesError, RegionEscape,
+                 HasProjectionTypes, ToPolyTraitRef, Ty};
 use middle::ty_fold::{mod, TypeFoldable, TypeFolder};
+use std::rc::Rc;
 use util::ppaux::Repr;
 
 pub type PolyProjectionObligation<'tcx> =
@@ -372,25 +374,30 @@ fn project_type<'cx,'tcx>(
         return Err(ProjectionTyError::TraitSelectionError(Overflow));
     }
 
+    let obligation_trait_ref =
+        selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate.trait_ref);
+
+    debug!("project: obligation_trait_ref={}", obligation_trait_ref.repr(selcx.tcx()));
+
+    if obligation_trait_ref.references_error() {
+        return Ok(ProjectedTy::Progress(selcx.tcx().types.err, vec!()));
+    }
+
     let mut candidates = ProjectionTyCandidateSet {
         vec: Vec::new(),
         ambiguous: false,
     };
 
-    assemble_candidates_from_object_type(selcx,
-                                         obligation,
-                                         &mut candidates);
+    assemble_candidates_from_param_env(selcx,
+                                       obligation,
+                                       &obligation_trait_ref,
+                                       &mut candidates);
 
-    if candidates.vec.is_empty() {
-        assemble_candidates_from_param_env(selcx,
-                                           obligation,
-                                           &mut candidates);
-
-        if let Err(e) = assemble_candidates_from_impls(selcx,
-                                                       obligation,
-                                                       &mut candidates) {
-            return Err(ProjectionTyError::TraitSelectionError(e));
-        }
+    if let Err(e) = assemble_candidates_from_impls(selcx,
+                                                   obligation,
+                                                   &obligation_trait_ref,
+                                                   &mut candidates) {
+        return Err(ProjectionTyError::TraitSelectionError(e));
     }
 
     debug!("{} candidates, ambiguous={}",
@@ -421,17 +428,20 @@ fn project_type<'cx,'tcx>(
 /// there that can answer this question.
 fn assemble_candidates_from_param_env<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
-    obligation:  &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTyObligation<'tcx>,
+    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
 {
     let env_predicates = selcx.param_env().caller_bounds.predicates.clone();
     let env_predicates = env_predicates.iter().cloned().collect();
-    assemble_candidates_from_predicates(selcx, obligation, candidate_set, env_predicates);
+    assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
+                                        candidate_set, env_predicates);
 }
 
 fn assemble_candidates_from_predicates<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
-    obligation:  &ProjectionTyObligation<'tcx>,
+    obligation: &ProjectionTyObligation<'tcx>,
+    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
     env_predicates: Vec<ty::Predicate<'tcx>>)
 {
@@ -445,7 +455,7 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
                 let is_match = infcx.probe(|_| {
                     let origin = infer::Misc(obligation.cause.span);
                     let obligation_poly_trait_ref =
-                        obligation.predicate.trait_ref.to_poly_trait_ref();
+                        obligation_trait_ref.to_poly_trait_ref();
                     let data_poly_trait_ref =
                         data.to_poly_trait_ref();
                     infcx.sub_poly_trait_refs(false,
@@ -467,36 +477,41 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
 fn assemble_candidates_from_object_type<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
     obligation:  &ProjectionTyObligation<'tcx>,
-    candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
+    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
+    candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
+    object_ty: Ty<'tcx>)
 {
     let infcx = selcx.infcx();
-    let trait_ref = infcx.resolve_type_vars_if_possible(&obligation.predicate.trait_ref);
-    debug!("assemble_candidates_from_object_type(trait_ref={})",
-           trait_ref.repr(infcx.tcx));
-    let self_ty = trait_ref.self_ty();
-    let data = match self_ty.sty {
+    debug!("assemble_candidates_from_object_type(object_ty={})",
+           object_ty.repr(infcx.tcx));
+    let data = match object_ty.sty {
         ty::ty_trait(ref data) => data,
-        _ => { return; }
+        _ => {
+            selcx.tcx().sess.span_bug(
+                obligation.cause.span,
+                format!("assemble_candidates_from_object_type called with non-object: {}",
+                        object_ty.repr(selcx.tcx()))[]);
+        }
     };
-    let projection_bounds = data.projection_bounds_with_self_ty(selcx.tcx(), self_ty);
+    let projection_bounds = data.projection_bounds_with_self_ty(selcx.tcx(), object_ty);
     let env_predicates = projection_bounds.iter()
                                           .map(|p| p.as_predicate())
                                           .collect();
-    assemble_candidates_from_predicates(selcx, obligation, candidate_set, env_predicates)
+    assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
+                                        candidate_set, env_predicates)
 }
 
 fn assemble_candidates_from_impls<'cx,'tcx>(
     selcx: &mut SelectionContext<'cx,'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
+    obligation_trait_ref: &Rc<ty::TraitRef<'tcx>>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
     -> Result<(), SelectionError<'tcx>>
 {
     // If we are resolving `<T as TraitRef<...>>::Item == Type`,
     // start out by selecting the predicate `T as TraitRef<...>`:
-    let trait_ref =
-        obligation.predicate.trait_ref.to_poly_trait_ref();
-    let trait_obligation =
-        obligation.with(trait_ref.to_poly_trait_predicate());
+    let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
+    let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
     let vtable = match selcx.select(&trait_obligation) {
         Ok(Some(vtable)) => vtable,
         Ok(None) => {
@@ -515,6 +530,11 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
             candidate_set.vec.push(
                 ProjectionTyCandidate::Impl(data));
         }
+        super::VtableObject(data) => {
+            assemble_candidates_from_object_type(
+                selcx, obligation, obligation_trait_ref, candidate_set,
+                data.object_ty);
+        }
         super::VtableParam(..) => {
             // This case tell us nothing about the value of an
             // associated type. Consider:
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index f9dced088f8..d09f2a250b0 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -24,8 +24,10 @@ use super::{ObligationCauseCode, BuiltinDerivedObligation};
 use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
 use super::{Selection};
 use super::{SelectionResult};
-use super::{VtableBuiltin, VtableImpl, VtableParam, VtableUnboxedClosure, VtableFnPointer};
-use super::{VtableImplData, VtableBuiltinData};
+use super::{VtableBuiltin, VtableImpl, VtableParam, VtableUnboxedClosure,
+            VtableFnPointer, VtableObject};
+use super::{VtableImplData, VtableObjectData, VtableBuiltinData};
+use super::object_safety;
 use super::{util};
 
 use middle::fast_reject;
@@ -147,6 +149,8 @@ enum SelectionCandidate<'tcx> {
     /// types generated for a fn pointer type (e.g., `fn(int)->int`)
     FnPointerCandidate,
 
+    ObjectCandidate,
+
     ErrorCandidate,
 }
 
@@ -289,6 +293,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
     }
 
+    fn evaluate_predicates_recursively<'a,'o,I>(&mut self,
+                                                stack: Option<&TraitObligationStack<'o, 'tcx>>,
+                                                mut predicates: I)
+                                                -> EvaluationResult<'tcx>
+        where I : Iterator<&'a PredicateObligation<'tcx>>, 'tcx:'a
+    {
+        let mut result = EvaluatedToOk;
+        for obligation in predicates {
+            match self.evaluate_predicate_recursively(stack, obligation) {
+                EvaluatedToErr(e) => { return EvaluatedToErr(e); }
+                EvaluatedToAmbig => { result = EvaluatedToAmbig; }
+                EvaluatedToOk => { }
+            }
+        }
+        result
+    }
+
     fn evaluate_predicate_recursively<'o>(&mut self,
                                           previous_stack: Option<&TraitObligationStack<'o, 'tcx>>,
                                           obligation: &PredicateObligation<'tcx>)
@@ -320,9 +341,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 EvaluatedToOk
             }
 
-            ty::Predicate::Projection(..) => {
-                // FIXME(#20296) -- we should be able to give a more precise answer here
-                EvaluatedToAmbig
+            ty::Predicate::Projection(ref data) => {
+                self.infcx.probe(|_| {
+                    let project_obligation = obligation.with(data.clone());
+                    match project::poly_project_and_unify_type(self, &project_obligation) {
+                        Ok(Some(subobligations)) => {
+                            self.evaluate_predicates_recursively(previous_stack,
+                                                                 subobligations.iter())
+                        }
+                        Ok(None) => {
+                            EvaluatedToAmbig
+                        }
+                        Err(_) => {
+                            EvaluatedToErr(Unimplemented)
+                        }
+                    }
+                })
             }
         }
     }
@@ -717,6 +751,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 try!(self.assemble_unboxed_closure_candidates(obligation, &mut candidates));
                 try!(self.assemble_fn_pointer_candidates(obligation, &mut candidates));
                 try!(self.assemble_candidates_from_impls(obligation, &mut candidates.vec));
+                self.assemble_candidates_from_object_ty(obligation, &mut candidates);
             }
         }
 
@@ -878,7 +913,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let matching_bounds =
             all_bounds.filter(
                 |bound| self.infcx.probe(
-                    |_| self.match_where_clause(obligation, bound.clone())).is_ok());
+                    |_| self.match_poly_trait_ref(obligation, bound.clone())).is_ok());
 
         let param_candidates =
             matching_bounds.map(|bound| ParamCandidate(bound));
@@ -945,7 +980,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
         match self_ty.sty {
-            ty::ty_infer(..) => {
+            ty::ty_infer(ty::TyVar(_)) => {
                 candidates.ambiguous = true; // could wind up being a fn() type
             }
 
@@ -991,6 +1026,62 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         Ok(())
     }
 
+    /// Search for impls that might apply to `obligation`.
+    fn assemble_candidates_from_object_ty(&mut self,
+                                          obligation: &TraitObligation<'tcx>,
+                                          candidates: &mut SelectionCandidateSet<'tcx>)
+    {
+        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
+
+        debug!("assemble_candidates_from_object_ty(self_ty={})",
+               self_ty.repr(self.tcx()));
+
+        // Object-safety candidates are only applicable to object-safe
+        // traits. Including this check is useful because it helps
+        // inference in cases of traits like `BorrowFrom`, which are
+        // not object-safe, and which rely on being able to infer the
+        // self-type from one of the other inputs. Without this check,
+        // these cases wind up being considered ambiguous due to a
+        // (spurious) ambiguity introduced here.
+        if !object_safety::is_object_safe(self.tcx(), obligation.predicate.to_poly_trait_ref()) {
+            return;
+        }
+
+        let poly_trait_ref = match self_ty.sty {
+            ty::ty_trait(ref data) => {
+                data.principal_trait_ref_with_self_ty(self.tcx(), self_ty)
+            }
+            ty::ty_infer(ty::TyVar(_)) => {
+                debug!("assemble_candidates_from_object_ty: ambiguous");
+                candidates.ambiguous = true; // could wind up being an object type
+                return;
+            }
+            _ => {
+                return;
+            }
+        };
+
+        debug!("assemble_candidates_from_object_ty: poly_trait_ref={}",
+               poly_trait_ref.repr(self.tcx()));
+
+        // see whether the object trait can be upcast to the trait we are looking for
+        let obligation_def_id = obligation.predicate.def_id();
+        let upcast_trait_ref = match util::upcast(self.tcx(), poly_trait_ref, obligation_def_id) {
+            Some(r) => r,
+            None => { return; }
+        };
+
+        debug!("assemble_candidates_from_object_ty: upcast_trait_ref={}",
+               upcast_trait_ref.repr(self.tcx()));
+
+        // check whether the upcast version of the trait-ref matches what we are looking for
+        if let Ok(()) = self.infcx.probe(|_| self.match_poly_trait_ref(obligation,
+                                                                       upcast_trait_ref.clone())) {
+            debug!("assemble_candidates_from_object_ty: matched, pushing candidate");
+            candidates.vec.push(ObjectCandidate);
+        }
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // WINNOW
     //
@@ -1026,15 +1117,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             selection: Selection<'tcx>)
                             -> EvaluationResult<'tcx>
     {
-        let mut result = EvaluatedToOk;
-        for obligation in selection.iter_nested() {
-            match self.evaluate_predicate_recursively(stack, obligation) {
-                EvaluatedToErr(e) => { return EvaluatedToErr(e); }
-                EvaluatedToAmbig => { result = EvaluatedToAmbig; }
-                EvaluatedToOk => { }
-            }
-        }
-        result
+        self.evaluate_predicates_recursively(stack, selection.iter_nested())
     }
 
     /// Returns true if `candidate_i` should be dropped in favor of `candidate_j`.
@@ -1544,6 +1627,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Ok(VtableUnboxedClosure(closure_def_id, substs))
             }
 
+            ObjectCandidate => {
+                let data = self.confirm_object_candidate(obligation);
+                Ok(VtableObject(data))
+            }
+
             FnPointerCandidate => {
                 let fn_type =
                     try!(self.confirm_fn_pointer_candidate(obligation));
@@ -1727,6 +1815,48 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                          nested: impl_predicates }
     }
 
+    fn confirm_object_candidate(&mut self,
+                                obligation: &TraitObligation<'tcx>)
+                                -> VtableObjectData<'tcx>
+    {
+        debug!("confirm_object_candidate({})",
+               obligation.repr(self.tcx()));
+
+        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
+        let poly_trait_ref = match self_ty.sty {
+            ty::ty_trait(ref data) => {
+                data.principal_trait_ref_with_self_ty(self.tcx(), self_ty)
+            }
+            _ => {
+                self.tcx().sess.span_bug(obligation.cause.span,
+                                         "object candidate with non-object");
+            }
+        };
+
+        let obligation_def_id = obligation.predicate.def_id();
+        let upcast_trait_ref = match util::upcast(self.tcx(),
+                                                  poly_trait_ref.clone(),
+                                                  obligation_def_id) {
+            Some(r) => r,
+            None => {
+                self.tcx().sess.span_bug(obligation.cause.span,
+                                         format!("unable to upcast from {} to {}",
+                                                 poly_trait_ref.repr(self.tcx()),
+                                                 obligation_def_id.repr(self.tcx())).as_slice());
+            }
+        };
+
+        match self.match_poly_trait_ref(obligation, upcast_trait_ref) {
+            Ok(()) => { }
+            Err(()) => {
+                self.tcx().sess.span_bug(obligation.cause.span,
+                                         "failed to match trait refs");
+            }
+        }
+
+        VtableObjectData { object_ty: self_ty }
+    }
+
     fn confirm_fn_pointer_candidate(&mut self,
                                     obligation: &TraitObligation<'tcx>)
                                     -> Result<ty::Ty<'tcx>,SelectionError<'tcx>>
@@ -1962,12 +2092,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             })
     }
 
-    fn match_where_clause(&mut self,
-                          obligation: &TraitObligation<'tcx>,
-                          where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
-                        -> Result<(),()>
+    fn match_poly_trait_ref(&mut self,
+                            obligation: &TraitObligation<'tcx>,
+                            where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
+                            -> Result<(),()>
     {
-        debug!("match_where_clause: obligation={} where_clause_trait_ref={}",
+        debug!("match_poly_trait_ref: obligation={} where_clause_trait_ref={}",
                obligation.repr(self.tcx()),
                where_clause_trait_ref.repr(self.tcx()));
 
@@ -2161,6 +2291,9 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
             ImplCandidate(a) => format!("ImplCandidate({})", a.repr(tcx)),
             ProjectionCandidate => format!("ProjectionCandidate"),
             FnPointerCandidate => format!("FnPointerCandidate"),
+            ObjectCandidate => {
+                format!("ObjectCandidate")
+            }
             UnboxedClosureCandidate(c, ref s) => {
                 format!("UnboxedClosureCandidate({},{})", c, s.repr(tcx))
             }
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index 109810fc7ee..41a59d6a5d8 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -238,6 +238,12 @@ impl<'tcx, N> fmt::Show for VtableImplData<'tcx, N> {
     }
 }
 
+impl<'tcx> fmt::Show for super::VtableObjectData<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "VtableObject(...)")
+    }
+}
+
 /// See `super::obligations_for_generics`
 pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      cause: ObligationCause<'tcx>,
@@ -291,6 +297,58 @@ pub fn predicate_for_builtin_bound<'tcx>(
     })
 }
 
+/// Cast a trait reference into a reference to one of its super
+/// traits; returns `None` if `target_trait_def_id` is not a
+/// supertrait.
+pub fn upcast<'tcx>(tcx: &ty::ctxt<'tcx>,
+                    source_trait_ref: ty::PolyTraitRef<'tcx>,
+                    target_trait_def_id: ast::DefId)
+                    -> Option<ty::PolyTraitRef<'tcx>>
+{
+    if source_trait_ref.def_id() == target_trait_def_id {
+        return Some(source_trait_ref); // shorcut the most common case
+    }
+
+    for super_trait_ref in supertraits(tcx, source_trait_ref) {
+        if super_trait_ref.def_id() == target_trait_def_id {
+            return Some(super_trait_ref);
+        }
+    }
+
+    None
+}
+
+/// Given an object of type `object_trait_ref`, returns the index of
+/// the method `n_method` found in the trait `trait_def_id` (which
+/// should be a supertrait of `object_trait_ref`) within the vtable
+/// for `object_trait_ref`.
+pub fn get_vtable_index_of_object_method<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                               object_trait_ref: ty::PolyTraitRef<'tcx>,
+                                               trait_def_id: ast::DefId,
+                                               method_index_in_trait: uint) -> uint {
+    // We need to figure the "real index" of the method in a
+    // listing of all the methods of an object. We do this by
+    // iterating down the supertraits of the object's trait until
+    // we find the trait the method came from, counting up the
+    // methods from them.
+    let mut method_count = 0;
+    ty::each_bound_trait_and_supertraits(tcx, &[object_trait_ref], |bound_ref| {
+        if bound_ref.def_id() == trait_def_id {
+            false
+        } else {
+            let trait_items = ty::trait_items(tcx, bound_ref.def_id());
+            for trait_item in trait_items.iter() {
+                match *trait_item {
+                    ty::MethodTraitItem(_) => method_count += 1,
+                    ty::TypeTraitItem(_) => {}
+                }
+            }
+            true
+        }
+    });
+    method_count + method_index_in_trait
+}
+
 impl<'tcx,O:Repr<'tcx>> Repr<'tcx> for super::Obligation<'tcx, O> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         format!("Obligation(predicate={},depth={})",
@@ -314,6 +372,10 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::Vtable<'tcx, N> {
                 format!("VtableFnPointer({})",
                         d.repr(tcx)),
 
+            super::VtableObject(ref d) =>
+                format!("VtableObject({})",
+                        d.repr(tcx)),
+
             super::VtableParam =>
                 format!("VtableParam"),
 
@@ -339,6 +401,13 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableBuiltinData<N> {
     }
 }
 
+impl<'tcx> Repr<'tcx> for super::VtableObjectData<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        format!("VtableObject(object_ty={})",
+                self.object_ty.repr(tcx))
+    }
+}
+
 impl<'tcx> Repr<'tcx> for super::SelectionError<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 7bc5d3d0708..999bc23c270 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -59,6 +59,7 @@ use middle::subst::{mod, Subst, Substs, VecPerParamSpace};
 use middle::traits;
 use middle::ty;
 use middle::ty_fold::{mod, TypeFoldable, TypeFolder};
+use middle::ty_walk::TypeWalker;
 use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
 use util::ppaux::{trait_store_to_string, ty_to_string};
 use util::ppaux::{Repr, UserString};
@@ -69,7 +70,7 @@ use util::nodemap::{FnvHashMap};
 use arena::TypedArena;
 use std::borrow::BorrowFrom;
 use std::cell::{Cell, RefCell};
-use std::cmp;
+use std::cmp::{mod, Ordering};
 use std::fmt::{mod, Show};
 use std::hash::{Hash, sip, Writer};
 use std::mem;
@@ -128,7 +129,7 @@ impl ImplOrTraitItemContainer {
     }
 }
 
-#[deriving(Clone)]
+#[deriving(Clone, Show)]
 pub enum ImplOrTraitItem<'tcx> {
     MethodTraitItem(Rc<Method<'tcx>>),
     TypeTraitItem(Rc<AssociatedType>),
@@ -173,7 +174,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> {
     }
 }
 
-#[deriving(Clone, Copy)]
+#[deriving(Clone, Copy, Show)]
 pub enum ImplOrTraitItemId {
     MethodTraitItemId(ast::DefId),
     TypeTraitItemId(ast::DefId),
@@ -232,7 +233,7 @@ impl<'tcx> Method<'tcx> {
     }
 }
 
-#[deriving(Clone, Copy)]
+#[deriving(Clone, Copy, Show)]
 pub struct AssociatedType {
     pub name: ast::Name,
     pub vis: ast::Visibility,
@@ -827,6 +828,9 @@ pub struct ctxt<'tcx> {
     /// parameters are never placed into this cache, because their
     /// results are dependent on the parameter environment.
     pub type_impls_sized_cache: RefCell<HashMap<Ty<'tcx>,bool>>,
+
+    /// Caches whether traits are object safe
+    pub object_safety_cache: RefCell<DefIdMap<bool>>,
 }
 
 // Flags that we track on types. These flags are propagated upwards
@@ -2384,6 +2388,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         repr_hint_cache: RefCell::new(DefIdMap::new()),
         type_impls_copy_cache: RefCell::new(HashMap::new()),
         type_impls_sized_cache: RefCell::new(HashMap::new()),
+        object_safety_cache: RefCell::new(DefIdMap::new()),
    }
 }
 
@@ -2831,59 +2836,61 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t
 
 pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
 
-pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where
-    F: FnMut(Ty<'tcx>),
+impl<'tcx> TyS<'tcx> {
+    /// Iterator that walks `self` and any types reachable from
+    /// `self`, in depth-first order. Note that just walks the types
+    /// that appear in `self`, it does not descend into the fields of
+    /// structs or variants. For example:
+    ///
+    /// ```notrust
+    /// int => { int }
+    /// Foo<Bar<int>> => { Foo<Bar<int>>, Bar<int>, int }
+    /// [int] => { [int], int }
+    /// ```
+    pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
+        TypeWalker::new(self)
+    }
+
+    /// Iterator that walks types reachable from `self`, in
+    /// depth-first order. Note that this is a shallow walk. For
+    /// example:
+    ///
+    /// ```notrust
+    /// int => { }
+    /// Foo<Bar<int>> => { Bar<int>, int }
+    /// [int] => { int }
+    /// ```
+    pub fn walk_children(&'tcx self) -> TypeWalker<'tcx> {
+        // Walks type reachable from `self` but not `self
+        let mut walker = self.walk();
+        let r = walker.next();
+        assert_eq!(r, Some(self));
+        walker
+    }
+}
+
+pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
+    where F: FnMut(Ty<'tcx>),
 {
-    maybe_walk_ty(ty, |ty| { f(ty); true });
+    for ty in ty_root.walk() {
+        f(ty);
+    }
 }
 
-pub fn maybe_walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where F: FnMut(Ty<'tcx>) -> bool {
-    // FIXME(#19596) This is a workaround, but there should be a better way to do this
-    fn maybe_walk_ty_<'tcx, F>(ty: Ty<'tcx>, f: &mut F) where F: FnMut(Ty<'tcx>) -> bool {
-        if !(*f)(ty) {
-            return;
-        }
-        match ty.sty {
-            ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
-            ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
-            ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty_(ty, f),
-            ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
-                maybe_walk_ty_(tm.ty, f);
-            }
-            ty_trait(box TyTrait { ref principal, .. }) => {
-                for subty in principal.0.substs.types.iter() {
-                    maybe_walk_ty_(*subty, f);
-                }
-            }
-            ty_projection(ProjectionTy { ref trait_ref, .. }) => {
-                for subty in trait_ref.substs.types.iter() {
-                    maybe_walk_ty_(*subty, f);
-                }
-            }
-            ty_enum(_, ref substs) |
-            ty_struct(_, ref substs) |
-            ty_unboxed_closure(_, _, ref substs) => {
-                for subty in substs.types.iter() {
-                    maybe_walk_ty_(*subty, f);
-                }
-            }
-            ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty_(*tt, f); } }
-            ty_bare_fn(_, ref ft) => {
-                for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
-                if let ty::FnConverging(output) = ft.sig.0.output {
-                    maybe_walk_ty_(output, f);
-                }
-            }
-            ty_closure(ref ft) => {
-                for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
-                if let ty::FnConverging(output) = ft.sig.0.output {
-                    maybe_walk_ty_(output, f);
-                }
-            }
+/// Walks `ty` and any types appearing within `ty`, invoking the
+/// callback `f` on each type. If the callback returns false, then the
+/// children of the current type are ignored.
+///
+/// Note: prefer `ty.walk()` where possible.
+pub fn maybe_walk_ty<'tcx,F>(ty_root: Ty<'tcx>, mut f: F)
+    where F : FnMut(Ty<'tcx>) -> bool
+{
+    let mut walker = ty_root.walk();
+    while let Some(ty) = walker.next() {
+        if !f(ty) {
+            walker.skip_current_subtree();
         }
     }
-
-    maybe_walk_ty_(ty, &mut f);
 }
 
 // Folds types from the bottom up.
@@ -4960,10 +4967,11 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
     }
 }
 
-/// Helper for looking things up in the various maps that are populated during typeck::collect
-/// (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of these share the pattern that if the
-/// id is local, it should have been loaded into the map by the `typeck::collect` phase.  If the
-/// def-id is external, then we have to go consult the crate loading code (and cache the result for
+/// Helper for looking things up in the various maps that are populated during
+/// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of
+/// these share the pattern that if the id is local, it should have been loaded
+/// into the map by the `typeck::collect` phase.  If the def-id is external,
+/// then we have to go consult the crate loading code (and cache the result for
 /// the future).
 fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
                                           def_id: ast::DefId,
@@ -6034,11 +6042,12 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
         return
     }
 
+    debug!("populate_implementations_for_type_if_necessary: searching for {}", type_id);
+
     let mut inherent_impls = Vec::new();
     csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
             |impl_def_id| {
-        let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
-                                                 impl_def_id);
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
 
         // Record the trait->implementation mappings, if applicable.
         let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
@@ -6120,22 +6129,9 @@ pub fn populate_implementations_for_trait_if_necessary(
 /// Given the def_id of an impl, return the def_id of the trait it implements.
 /// If it implements no trait, return `None`.
 pub fn trait_id_of_impl(tcx: &ctxt,
-                        def_id: ast::DefId) -> Option<ast::DefId> {
-    let node = match tcx.map.find(def_id.node) {
-        Some(node) => node,
-        None => return None
-    };
-    match node {
-        ast_map::NodeItem(item) => {
-            match item.node {
-                ast::ItemImpl(_, _, Some(ref trait_ref), _, _) => {
-                    Some(node_id_to_trait_ref(tcx, trait_ref.ref_id).def_id)
-                }
-                _ => None
-            }
-        }
-        _ => None
-    }
+                        def_id: ast::DefId)
+                        -> Option<ast::DefId> {
+    ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id)
 }
 
 /// If the given def ID describes a method belonging to an impl, return the
@@ -7269,7 +7265,7 @@ impl<T:ReferencesError> ReferencesError for Binder<T> {
 
 impl<T:ReferencesError> ReferencesError for Rc<T> {
     fn references_error(&self) -> bool {
-        (&*self).references_error()
+        (&**self).references_error()
     }
 }
 
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 83d2f6fb0e6..abbf530529b 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -56,7 +56,7 @@ pub trait TypeFoldable<'tcx> {
 /// default implementation that does an "identity" fold. Within each
 /// identity fold, it should invoke `foo.fold_with(self)` to fold each
 /// sub-item.
-pub trait TypeFolder<'tcx> {
+pub trait TypeFolder<'tcx> : Sized {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
 
     /// Invoked by the `super_*` routines when we enter a region
@@ -503,6 +503,15 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
             }
             traits::VtableParam => traits::VtableParam,
             traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
+            traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
+        }
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> {
+    fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableObjectData<'tcx> {
+        traits::VtableObjectData {
+            object_ty: self.object_ty.fold_with(folder)
         }
     }
 }
diff --git a/src/librustc/middle/ty_walk.rs b/src/librustc/middle/ty_walk.rs
new file mode 100644
index 00000000000..406ebf4bc38
--- /dev/null
+++ b/src/librustc/middle/ty_walk.rs
@@ -0,0 +1,112 @@
+// 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.
+
+//! An iterator over the type substructure.
+
+use middle::ty::{mod, Ty};
+use std::iter::Iterator;
+
+pub struct TypeWalker<'tcx> {
+    stack: Vec<Ty<'tcx>>,
+    last_subtree: uint,
+}
+
+impl<'tcx> TypeWalker<'tcx> {
+    pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> {
+        TypeWalker { stack: vec!(ty), last_subtree: 1, }
+    }
+
+    fn push_subtypes(&mut self, parent_ty: Ty<'tcx>) {
+        match parent_ty.sty {
+            ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
+            ty::ty_str | ty::ty_infer(_) | ty::ty_param(_) | ty::ty_err => {
+            }
+            ty::ty_uniq(ty) | ty::ty_vec(ty, _) | ty::ty_open(ty) => {
+                self.stack.push(ty);
+            }
+            ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
+                self.stack.push(mt.ty);
+            }
+            ty::ty_projection(ref data) => {
+                self.push_reversed(data.trait_ref.substs.types.as_slice());
+            }
+            ty::ty_trait(box ty::TyTrait { ref principal, .. }) => {
+                self.push_reversed(principal.substs().types.as_slice());
+            }
+            ty::ty_enum(_, ref substs) |
+            ty::ty_struct(_, ref substs) |
+            ty::ty_unboxed_closure(_, _, ref substs) => {
+                self.push_reversed(substs.types.as_slice());
+            }
+            ty::ty_tup(ref ts) => {
+                self.push_reversed(ts.as_slice());
+            }
+            ty::ty_bare_fn(_, ref ft) => {
+                self.push_sig_subtypes(&ft.sig);
+            }
+            ty::ty_closure(ref ft) => {
+                self.push_sig_subtypes(&ft.sig);
+            }
+        }
+    }
+
+    fn push_sig_subtypes(&mut self, sig: &ty::PolyFnSig<'tcx>) {
+        match sig.0.output {
+            ty::FnConverging(output) => { self.stack.push(output); }
+            ty::FnDiverging => { }
+        }
+        self.push_reversed(sig.0.inputs.as_slice());
+    }
+
+    fn push_reversed(&mut self, tys: &[Ty<'tcx>]) {
+        // We push slices on the stack in reverse order so as to
+        // maintain a pre-order traversal. As of the time of this
+        // writing, the fact that the traversal is pre-order is not
+        // known to be significant to any code, but it seems like the
+        // natural order one would expect (basically, the order of the
+        // types as they are written).
+        for &ty in tys.iter().rev() {
+            self.stack.push(ty);
+        }
+    }
+
+    /// Skips the subtree of types corresponding to the last type
+    /// returned by `next()`.
+    ///
+    /// Example: Imagine you are walking `Foo<Bar<int>, uint>`.
+    ///
+    /// ```rust
+    /// let mut iter: TypeWalker = ...;
+    /// iter.next(); // yields Foo
+    /// iter.next(); // yields Bar<int>
+    /// iter.skip_current_subtree(); // skips int
+    /// iter.next(); // yields uint
+    /// ```
+    pub fn skip_current_subtree(&mut self) {
+        self.stack.truncate(self.last_subtree);
+    }
+}
+
+impl<'tcx> Iterator<Ty<'tcx>> for TypeWalker<'tcx> {
+    fn next(&mut self) -> Option<Ty<'tcx>> {
+        debug!("next(): stack={}", self.stack);
+        match self.stack.pop() {
+            None => {
+                return None;
+            }
+            Some(ty) => {
+                self.last_subtree = self.stack.len();
+                self.push_subtypes(ty);
+                debug!("next: stack={}", self.stack);
+                Some(ty)
+            }
+        }
+    }
+}
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 19ac6d466fb..f299ea939ed 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -394,6 +394,7 @@ macro_rules! cgoptions {
 
     mod cgsetters {
         use super::{CodegenOptions, Passes, SomePasses, AllPasses};
+        use std::str::from_str;
 
         $(
             pub fn $opt(cg: &mut CodegenOptions, v: Option<&str>) -> bool {
@@ -743,7 +744,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
         opt::multi("l", "",   "Link the generated crate(s) to the specified native
                              library NAME. The optional KIND can be one of,
                              static, dylib, or framework. If omitted, dylib is
-                             assumed.", "NAME[:KIND]"),
+                             assumed.", "[KIND=]NAME"),
         opt::multi("", "crate-type", "Comma separated list of types of crates
                                     for the compiler to emit",
                    "[bin|lib|rlib|dylib|staticlib]"),
@@ -1016,6 +1017,24 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     }
 
     let libs = matches.opt_strs("l").into_iter().map(|s| {
+        let mut parts = s.splitn(1, '=');
+        let kind = parts.next().unwrap();
+        if let Some(name) = parts.next() {
+            let kind = match kind {
+                "dylib" => cstore::NativeUnknown,
+                "framework" => cstore::NativeFramework,
+                "static" => cstore::NativeStatic,
+                s => {
+                    early_error(format!("unknown library kind `{}`, expected \
+                                         one of dylib, framework, or static",
+                                        s)[]);
+                }
+            };
+            return (name.to_string(), kind)
+        }
+
+        // FIXME(acrichto) remove this once crates have stopped using it, this
+        //                 is deprecated behavior now.
         let mut parts = s.rsplitn(1, ':');
         let kind = parts.next().unwrap();
         let (name, kind) = match (parts.next(), kind) {
diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs
index 8a6217a49f5..56b4cae2e43 100644
--- a/src/librustc/session/search_paths.rs
+++ b/src/librustc/session/search_paths.rs
@@ -34,15 +34,14 @@ impl SearchPaths {
     }
 
     pub fn add_path(&mut self, path: &str) {
-        let (kind, path) = if path.ends_with(":native") {
-            (PathKind::Native, path.slice_to(path.len() - ":native".len()))
-        } else if path.ends_with(":crate") {
-            (PathKind::Crate, path.slice_to(path.len() - ":crate".len()))
-        } else if path.ends_with(":dependency") {
-            (PathKind::Dependency,
-             path.slice_to(path.len() - ":dependency".len()))
-        } else if path.ends_with(":all") {
-            (PathKind::All, path.slice_to(path.len() - ":all".len()))
+        let (kind, path) = if path.starts_with("native=") {
+            (PathKind::Native, path.slice_from("native=".len()))
+        } else if path.starts_with("crate=") {
+            (PathKind::Crate, path.slice_from("crate=".len()))
+        } else if path.starts_with("dependency=") {
+            (PathKind::Dependency, path.slice_from("dependency=".len()))
+        } else if path.starts_with("all=") {
+            (PathKind::All, path.slice_from("all=".len()))
         } else {
             (PathKind::All, path)
         };
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index cb547df7d9c..2bb99a7141f 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -32,6 +32,7 @@
 #![allow(unknown_features)]
 #![feature(globs, phase, macro_rules, slicing_syntax)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
 
 #[phase(plugin, link)]
 extern crate log;
diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
index 73b345a70af..8d3aa397f30 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
@@ -33,7 +33,7 @@ impl<'tcx> MoveErrorCollector<'tcx> {
     }
 
     pub fn report_potential_errors<'a>(&self, bccx: &BorrowckCtxt<'a, 'tcx>) {
-        report_move_errors(bccx, self.errors.borrow().deref())
+        report_move_errors(bccx, &*self.errors.borrow())
     }
 }
 
diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs
index e2813c8e988..ac6b962d647 100644
--- a/src/librustc_borrowck/graphviz.rs
+++ b/src/librustc_borrowck/graphviz.rs
@@ -24,6 +24,7 @@ use rustc::middle::cfg::{CFGIndex};
 use rustc::middle::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
 use rustc::middle::dataflow;
 use std::rc::Rc;
+use std::borrow::IntoCow;
 
 #[deriving(Show, Copy)]
 pub enum Variant {
diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs
index 664d470b11b..b886883c73a 100644
--- a/src/librustc_borrowck/lib.rs
+++ b/src/librustc_borrowck/lib.rs
@@ -16,10 +16,12 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
+#![allow(unknown_features)]
 #![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
 #![allow(non_camel_case_types)]
 
 #[phase(plugin, link)] extern crate log;
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 91902b90673..a92c2fe2ccb 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -28,7 +28,7 @@ use rustc_trans::save;
 use rustc_trans::trans;
 use rustc_typeck as typeck;
 
-use serialize::{json, Encodable};
+use serialize::json;
 
 use std::io;
 use std::io::fs;
@@ -143,10 +143,7 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
     });
 
     if sess.opts.debugging_opts & config::AST_JSON_NOEXPAND != 0 {
-        let mut stdout = io::BufferedWriter::new(io::stdout());
-        let mut json = json::PrettyEncoder::new(&mut stdout);
-        // unwrapping so IoError isn't ignored
-        krate.encode(&mut json).unwrap();
+        println!("{}", json::as_json(&krate));
     }
 
     if sess.show_span() {
@@ -338,10 +335,7 @@ pub fn assign_node_ids_and_map<'ast>(sess: &Session,
                    ast_map::map_crate(forest, NodeIdAssigner { sess: sess }));
 
     if sess.opts.debugging_opts & config::AST_JSON != 0 {
-        let mut stdout = io::BufferedWriter::new(io::stdout());
-        let mut json = json::PrettyEncoder::new(&mut stdout);
-        // unwrapping so IoError isn't ignored
-        map.krate().encode(&mut json).unwrap();
+        println!("{}", json::as_json(map.krate()));
     }
 
     map
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 181f38d8993..be55da8c59d 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -54,9 +54,11 @@ use rustc::metadata;
 use rustc::DIAGNOSTICS;
 
 use std::any::AnyRefExt;
+use std::cmp::Ordering::Equal;
 use std::io;
 use std::iter::repeat;
 use std::os;
+use std::sync::mpsc::channel;
 use std::thread;
 
 use rustc::session::early_error;
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 773ea30d401..a046d9d5d39 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -154,7 +154,7 @@ trait PrinterSupport<'ast>: pprust::PpAnn {
     ///
     /// (Rust does not yet support upcasting from a trait object to
     /// an object for one of its super-traits.)
-    fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self as &pprust::PpAnn }
+    fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn;
 }
 
 struct NoAnn<'ast> {
@@ -168,6 +168,8 @@ impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
     fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
         self.ast_map.as_ref()
     }
+
+    fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
 }
 
 impl<'ast> pprust::PpAnn for NoAnn<'ast> {}
@@ -183,6 +185,8 @@ impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
     fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
         self.ast_map.as_ref()
     }
+
+    fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
 }
 
 impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
@@ -232,6 +236,8 @@ impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
     fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
         self.ast_map.as_ref()
     }
+
+    fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
 }
 
 impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
@@ -265,6 +271,8 @@ impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
     fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'tcx>> {
         Some(&self.analysis.ty_cx.map)
     }
+
+    fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
 }
 
 impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 6329acfb578..eddcc750068 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -34,8 +34,6 @@ use syntax::codemap::{Span, CodeMap, DUMMY_SP};
 use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
 use syntax::parse::token;
 
-use arena::TypedArena;
-
 struct Env<'a, 'tcx: 'a> {
     infcx: &'a infer::InferCtxt<'a, 'tcx>,
 }
@@ -831,3 +829,57 @@ fn subst_region_renumber_region() {
         assert_eq!(t_substituted, t_expected);
     })
 }
+
+#[test]
+fn walk_ty() {
+    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
+        let tcx = env.infcx.tcx;
+        let int_ty = tcx.types.int;
+        let uint_ty = tcx.types.uint;
+        let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty));
+        let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty));
+        let uniq_ty = ty::mk_uniq(tcx, tup2_ty);
+        let walked: Vec<_> = uniq_ty.walk().collect();
+        assert_eq!(vec!(uniq_ty,
+                        tup2_ty,
+                        tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
+                        tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
+                        uint_ty),
+                   walked);
+    })
+}
+
+#[test]
+fn walk_ty_skip_subtree() {
+    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
+        let tcx = env.infcx.tcx;
+        let int_ty = tcx.types.int;
+        let uint_ty = tcx.types.uint;
+        let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty));
+        let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty));
+        let uniq_ty = ty::mk_uniq(tcx, tup2_ty);
+
+        // types we expect to see (in order), plus a boolean saying
+        // whether to skip the subtree.
+        let mut expected = vec!((uniq_ty, false),
+                                (tup2_ty, false),
+                                (tup1_ty, false),
+                                (int_ty, false),
+                                (uint_ty, false),
+                                (int_ty, false),
+                                (uint_ty, false),
+                                (tup1_ty, true), // skip the int/uint/int/uint
+                                (uint_ty, false));
+        expected.reverse();
+
+        let mut walker = uniq_ty.walk();
+        while let Some(t) = walker.next() {
+            debug!("walked to {}", t);
+            let (expected_ty, skip) = expected.pop().unwrap();
+            assert_eq!(t, expected_ty);
+            if skip { walker.skip_current_subtree(); }
+        }
+
+        assert!(expected.is_empty());
+    })
+}
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
index 6c3778787e2..53992d4567a 100644
--- a/src/librustc_llvm/archive_ro.rs
+++ b/src/librustc_llvm/archive_ro.rs
@@ -13,8 +13,9 @@
 use libc;
 use ArchiveRef;
 
-use std::raw;
+use std::c_str::ToCStr;
 use std::mem;
+use std::raw;
 
 pub struct ArchiveRO {
     ptr: ArchiveRef,
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index efb9b636247..aa3ac83c027 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -61,8 +61,9 @@ use syntax::parse::token::{mod, special_idents};
 use syntax::codemap::{Span, DUMMY_SP};
 use syntax::visit::{mod, Visitor};
 
-use std::rc::Rc;
 use std::mem::replace;
+use std::ops::{Deref, DerefMut};
+use std::rc::Rc;
 
 // Specifies how duplicates should be handled when adding a child item if
 // another item exists with the same name in some namespace.
@@ -95,13 +96,15 @@ struct GraphBuilder<'a, 'b:'a, 'tcx:'b> {
     resolver: &'a mut Resolver<'b, 'tcx>
 }
 
-impl<'a, 'b:'a, 'tcx:'b> Deref<Resolver<'b, 'tcx>> for GraphBuilder<'a, 'b, 'tcx> {
+impl<'a, 'b:'a, 'tcx:'b> Deref for GraphBuilder<'a, 'b, 'tcx> {
+    type Target = Resolver<'b, 'tcx>;
+
     fn deref(&self) -> &Resolver<'b, 'tcx> {
         &*self.resolver
     }
 }
 
-impl<'a, 'b:'a, 'tcx:'b> DerefMut<Resolver<'b, 'tcx>> for GraphBuilder<'a, 'b, 'tcx> {
+impl<'a, 'b:'a, 'tcx:'b> DerefMut for GraphBuilder<'a, 'b, 'tcx> {
     fn deref_mut(&mut self) -> &mut Resolver<'b, 'tcx> {
         &mut *self.resolver
     }
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 78527315199..1bfe4c0407a 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -17,6 +17,8 @@
 // `use` directives.
 //
 
+use std::ops::{Deref, DerefMut};
+
 use Resolver;
 use Namespace::{TypeNS, ValueNS};
 
@@ -33,13 +35,15 @@ struct UnusedImportCheckVisitor<'a, 'b:'a, 'tcx:'b> {
 }
 
 // Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
-impl<'a, 'b, 'tcx:'b> Deref<Resolver<'b, 'tcx>> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx:'b> Deref for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
+    type Target = Resolver<'b, 'tcx>;
+
     fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> {
         &*self.resolver
     }
 }
 
-impl<'a, 'b, 'tcx:'b> DerefMut<Resolver<'b, 'tcx>> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx:'b> DerefMut for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
     fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> {
         &mut *self.resolver
     }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 11328bedcc4..4ac9224969c 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -18,6 +18,7 @@
 
 #![feature(globs, phase, slicing_syntax)]
 #![feature(rustc_diagnostic_macros)]
+#![feature(associated_types)]
 
 #[phase(plugin, link)] extern crate log;
 #[phase(plugin, link)] extern crate syntax;
@@ -3402,7 +3403,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn resolve_local(&mut self, local: &Local) {
         // Resolve the type.
-        self.resolve_type(&*local.ty);
+        if let Some(ref ty) = local.ty {
+            self.resolve_type(&**ty);
+        }
 
         // Resolve the initializer, if necessary.
         match local.init {
diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs
index 9c2437c376d..ff415750d64 100644
--- a/src/librustc_resolve/record_exports.rs
+++ b/src/librustc_resolve/record_exports.rs
@@ -27,6 +27,7 @@ use rustc::middle::def::Export;
 use syntax::ast;
 use syntax::parse::token;
 
+use std::ops::{Deref, DerefMut};
 use std::rc::Rc;
 
 struct ExportRecorder<'a, 'b:'a, 'tcx:'b> {
@@ -34,13 +35,15 @@ struct ExportRecorder<'a, 'b:'a, 'tcx:'b> {
 }
 
 // Deref and DerefMut impls allow treating ExportRecorder as Resolver.
-impl<'a, 'b, 'tcx:'b> Deref<Resolver<'b, 'tcx>> for ExportRecorder<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx:'b> Deref for ExportRecorder<'a, 'b, 'tcx> {
+    type Target = Resolver<'b, 'tcx>;
+
     fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> {
         &*self.resolver
     }
 }
 
-impl<'a, 'b, 'tcx:'b> DerefMut<Resolver<'b, 'tcx>> for ExportRecorder<'a, 'b, 'tcx> {
+impl<'a, 'b, 'tcx:'b> DerefMut for ExportRecorder<'a, 'b, 'tcx> {
     fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> {
         &mut *self.resolver
     }
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index 1271330897e..7cf4bafe032 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -20,6 +20,7 @@ use rustc::util::common::time;
 use libc;
 use flate;
 
+use std::c_str::ToCStr;
 use std::iter;
 use std::mem;
 use std::num::Int;
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index a6f2c7dfed0..5cd62675c1d 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -30,6 +30,7 @@ use std::ptr;
 use std::str;
 use std::mem;
 use std::sync::{Arc, Mutex};
+use std::sync::mpsc::channel;
 use std::thread;
 use libc::{c_uint, c_int, c_void};
 
@@ -928,13 +929,13 @@ fn run_work_multithreaded(sess: &Session,
                 }
             }
 
-            tx.take().unwrap().send(());
+            tx.take().unwrap().send(()).unwrap();
         }).detach();
     }
 
     let mut panicked = false;
     for rx in futures.into_iter() {
-        match rx.recv_opt() {
+        match rx.recv() {
             Ok(()) => {},
             Err(_) => {
                 panicked = true;
@@ -1009,7 +1010,7 @@ unsafe fn configure_llvm(sess: &Session) {
         }
     }
 
-    INIT.doit(|| {
+    INIT.call_once(|| {
         llvm::LLVMInitializePasses();
 
         // Only initialize the platforms supported by Rust here, because
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 784002287b7..5ffe9b2d647 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -22,10 +22,12 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
+#![allow(unknown_features)]
 #![feature(default_type_params, globs, macro_rules, phase, quote)]
 #![feature(slicing_syntax, unsafe_destructor)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
 
 extern crate arena;
 extern crate flate;
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 51ea0af8e10..73961f00d70 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -1202,8 +1202,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                         let glob_map = &self.analysis.glob_map;
                         let glob_map = glob_map.as_ref().unwrap();
                         if glob_map.contains_key(&id) {
-                            let names = glob_map.index(&id);
-                            for n in names.iter() {
+                            for n in glob_map[id].iter() {
                                 if name_string.len() > 0 {
                                     name_string.push_str(", ");
                                 }
@@ -1496,7 +1495,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
         self.collected_paths.clear();
 
         // Just walk the initialiser and type (don't want to walk the pattern again).
-        self.visit_ty(&*l.ty);
+        visit::walk_ty_opt(self, &l.ty);
         visit::walk_expr_opt(self, &l.init);
     }
 }
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 18155d75680..bf53885e9e5 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -3097,7 +3097,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
         use std::sync::{Once, ONCE_INIT};
         static INIT: Once = ONCE_INIT;
         static mut POISONED: bool = false;
-        INIT.doit(|| {
+        INIT.call_once(|| {
             if llvm::LLVMStartMultithreaded() != 1 {
                 // use an extra bool to make sure that all future usage of LLVM
                 // cannot proceed despite the Once not running more than once.
diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs
index b39dbd71117..97f0b92a290 100644
--- a/src/librustc_trans/trans/builder.rs
+++ b/src/librustc_trans/trans/builder.rs
@@ -20,7 +20,7 @@ use trans::machine::llalign_of_pref;
 use trans::type_::Type;
 use util::nodemap::FnvHashMap;
 use libc::{c_uint, c_char};
-use std::string::String;
+use std::c_str::ToCStr;
 use syntax::codemap::Span;
 
 pub struct Builder<'a, 'tcx: 'a> {
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index c651255226b..1a0007cf0fc 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -853,7 +853,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
 /// local in `bcx.fcx.lllocals`.
 /// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
-    if fn_should_be_ignored(bcx.fcx) {
+    if bcx.unreachable.get() || fn_should_be_ignored(bcx.fcx) {
         return;
     }
 
@@ -897,7 +897,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                 env_index: uint,
                                                 captured_by_ref: bool,
                                                 span: Span) {
-    if fn_should_be_ignored(bcx.fcx) {
+    if bcx.unreachable.get() || fn_should_be_ignored(bcx.fcx) {
         return;
     }
 
@@ -980,7 +980,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                  variable_ident: ast::Ident,
                                                  binding: BindingInfo<'tcx>) {
-    if fn_should_be_ignored(bcx.fcx) {
+    if bcx.unreachable.get() || fn_should_be_ignored(bcx.fcx) {
         return;
     }
 
@@ -1020,7 +1020,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// argument in `bcx.fcx.lllocals`.
 /// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
-    if fn_should_be_ignored(bcx.fcx) {
+    if bcx.unreachable.get() || fn_should_be_ignored(bcx.fcx) {
         return;
     }
 
@@ -1074,7 +1074,7 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
 /// loop variable in `bcx.fcx.lllocals`.
 /// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_for_loop_var_metadata(bcx: Block, pat: &ast::Pat) {
-    if fn_should_be_ignored(bcx.fcx) {
+    if bcx.unreachable.get() || fn_should_be_ignored(bcx.fcx) {
         return;
     }
 
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index 83765270ef1..99dc971ed94 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -26,6 +26,7 @@ use trans::type_of;
 use middle::ty::{mod, Ty};
 use middle::subst::{Substs};
 use std::cmp;
+use std::c_str::ToCStr;
 use libc::c_uint;
 use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi};
 use syntax::abi::{RustIntrinsic, Rust, RustCall, Stdcall, Fastcall, System};
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 9535ffaec0e..99624f1b1e7 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use arena::TypedArena;
 use back::abi;
-use llvm;
-use llvm::ValueRef;
+use back::link;
+use llvm::{mod, ValueRef, get_param};
 use metadata::csearch;
-use middle::subst::{Substs};
+use middle::subst::{Subst, Substs};
 use middle::subst::VecPerParamSpace;
 use middle::subst;
 use middle::traits;
@@ -370,6 +370,10 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let llfn = trans_fn_pointer_shim(bcx.ccx(), fn_ty);
             Callee { bcx: bcx, data: Fn(llfn) }
         }
+        traits::VtableObject(ref data) => {
+            let llfn = trans_object_shim(bcx.ccx(), data.object_ty, trait_id, n_method);
+            Callee { bcx: bcx, data: Fn(llfn) }
+        }
         traits::VtableBuiltin(..) |
         traits::VtableParam(..) => {
             bcx.sess().bug(
@@ -503,6 +507,137 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     };
 }
 
+/// Generate a shim function that allows an object type like `SomeTrait` to
+/// implement the type `SomeTrait`. Imagine a trait definition:
+///
+///    trait SomeTrait { fn get(&self) -> int; ... }
+///
+/// And a generic bit of code:
+///
+///    fn foo<T:SomeTrait>(t: &T) {
+///        let x = SomeTrait::get;
+///        x(t)
+///    }
+///
+/// What is the value of `x` when `foo` is invoked with `T=SomeTrait`?
+/// The answer is that it it is a shim function generate by this
+/// routine:
+///
+///    fn shim(t: &SomeTrait) -> int {
+///        // ... call t.get() virtually ...
+///    }
+///
+/// In fact, all virtual calls can be thought of as normal trait calls
+/// that go through this shim function.
+pub fn trans_object_shim<'a, 'tcx>(
+    ccx: &'a CrateContext<'a, 'tcx>,
+    object_ty: Ty<'tcx>,
+    trait_id: ast::DefId,
+    method_offset_in_trait: uint)
+    -> ValueRef
+{
+    let _icx = push_ctxt("trans_object_shim");
+    let tcx = ccx.tcx();
+
+    debug!("trans_object_shim(object_ty={}, trait_id={}, n_method={})",
+           object_ty.repr(tcx),
+           trait_id.repr(tcx),
+           method_offset_in_trait);
+
+    let object_trait_ref =
+        match object_ty.sty {
+            ty::ty_trait(ref data) => {
+                data.principal_trait_ref_with_self_ty(tcx, object_ty)
+            }
+            _ => {
+                tcx.sess.bug(format!("trans_object_shim() called on non-object: {}",
+                                     object_ty.repr(tcx)).as_slice());
+            }
+        };
+
+    // Upcast to the trait in question and extract out the substitutions.
+    let upcast_trait_ref = traits::upcast(ccx.tcx(), object_trait_ref.clone(), trait_id).unwrap();
+    let object_substs = upcast_trait_ref.substs().clone().erase_regions();
+    debug!("trans_object_shim: object_substs={}", object_substs.repr(tcx));
+
+    // Lookup the type of this method as deeclared in the trait and apply substitutions.
+    let method_ty = match ty::trait_item(tcx, trait_id, method_offset_in_trait) {
+        ty::MethodTraitItem(method) => method,
+        ty::TypeTraitItem(_) => {
+            tcx.sess.bug("can't create a method shim for an associated type")
+        }
+    };
+    let fty = method_ty.fty.subst(tcx, &object_substs);
+    let fty = tcx.mk_bare_fn(fty);
+    debug!("trans_object_shim: fty={}", fty.repr(tcx));
+
+    //
+    let method_bare_fn_ty =
+        ty::mk_bare_fn(tcx, None, fty);
+    let function_name =
+        link::mangle_internal_name_by_type_and_seq(ccx, method_bare_fn_ty, "object_shim");
+    let llfn =
+        decl_internal_rust_fn(ccx, method_bare_fn_ty, function_name.as_slice());
+
+    //
+    let block_arena = TypedArena::new();
+    let empty_substs = Substs::trans_empty();
+    let fcx = new_fn_ctxt(ccx,
+                          llfn,
+                          ast::DUMMY_NODE_ID,
+                          false,
+                          fty.sig.0.output,
+                          &empty_substs,
+                          None,
+                          &block_arena);
+    let mut bcx = init_function(&fcx, false, fty.sig.0.output);
+
+    // the first argument (`self`) will be a trait object
+    let llobject = get_param(fcx.llfn, fcx.arg_pos(0) as u32);
+
+    debug!("trans_object_shim: llobject={}",
+           bcx.val_to_string(llobject));
+
+    // the remaining arguments will be, well, whatever they are
+    let llargs: Vec<_> =
+        fty.sig.0.inputs[1..].iter()
+        .enumerate()
+        .map(|(i, _)| {
+            let llarg = get_param(fcx.llfn, fcx.arg_pos(i+1) as u32);
+            debug!("trans_object_shim: input #{} == {}",
+                   i, bcx.val_to_string(llarg));
+            llarg
+        })
+        .collect();
+    assert!(!fcx.needs_ret_allocas);
+
+    let dest =
+        fcx.llretslotptr.get().map(
+            |_| expr::SaveIn(fcx.get_ret_slot(bcx, fty.sig.0.output, "ret_slot")));
+
+    let method_offset_in_vtable =
+        traits::get_vtable_index_of_object_method(bcx.tcx(),
+                                                  object_trait_ref.clone(),
+                                                  trait_id,
+                                                  method_offset_in_trait);
+    debug!("trans_object_shim: method_offset_in_vtable={}",
+           method_offset_in_vtable);
+
+    bcx = trans_call_inner(bcx,
+                           None,
+                           method_bare_fn_ty,
+                           |bcx, _| trans_trait_callee_from_llval(bcx,
+                                                                  method_bare_fn_ty,
+                                                                  method_offset_in_vtable,
+                                                                  llobject),
+                           ArgVals(llargs.as_slice()),
+                           dest).bcx;
+
+    finish_fn(&fcx, bcx, fty.sig.0.output);
+
+    llfn
+}
+
 /// Creates a returns a dynamic vtable for the given type and vtable origin.
 /// This is used only for objects.
 ///
@@ -560,6 +695,14 @@ pub fn get_vtable<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 let llfn = vec![trans_fn_pointer_shim(bcx.ccx(), bare_fn_ty)];
                 llfn.into_iter()
             }
+            traits::VtableObject(ref data) => {
+                // this would imply that the Self type being erased is
+                // an object type; this cannot happen because we
+                // cannot cast an unsized type into a trait object
+                bcx.sess().bug(
+                    format!("cannot get vtable for an object type: {}",
+                            data.repr(bcx.tcx())).as_slice());
+            }
             traits::VtableParam => {
                 bcx.sess().bug(
                     format!("resolved vtable for {} to bad vtable {} in trans",
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index a751b65a0f8..ee859bbe8f5 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -633,17 +633,16 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
               target_trait_def_id: ast::DefId)
               -> ty::PolyTraitRef<'tcx>
     {
-        for super_trait_ref in traits::supertraits(self.tcx(), source_trait_ref.clone()) {
-            if super_trait_ref.def_id() == target_trait_def_id {
-                return super_trait_ref;
+        match traits::upcast(self.tcx(), source_trait_ref.clone(), target_trait_def_id) {
+            Some(super_trait_ref) => super_trait_ref,
+            None => {
+                self.tcx().sess.span_bug(
+                    self.span,
+                    format!("cannot upcast `{}` to `{}`",
+                            source_trait_ref.repr(self.tcx()),
+                            target_trait_def_id.repr(self.tcx()))[]);
             }
         }
-
-        self.tcx().sess.span_bug(
-            self.span,
-            format!("cannot upcast `{}` to `{}`",
-                    source_trait_ref.repr(self.tcx()),
-                    target_trait_def_id.repr(self.tcx()))[]);
     }
 
     fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &ty::Binder<T>) -> T
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index f00e3e2d452..52860abb6f9 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -267,6 +267,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             return; // already visited
         }
 
+        debug!("assemble_inherent_impl_probe {}", impl_def_id);
+
         let method = match impl_method(self.tcx(), impl_def_id, self.method_name) {
             Some(m) => m,
             None => { return; } // No method with correct name on this impl
@@ -308,7 +310,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(), self_ty);
         self.elaborate_bounds(&[trait_ref.clone()], false, |this, new_trait_ref, m, method_num| {
             let vtable_index =
-                get_method_index(tcx, &new_trait_ref, trait_ref.clone(), method_num);
+                traits::get_vtable_index_of_object_method(tcx,
+                                                          trait_ref.clone(),
+                                                          new_trait_ref.def_id(),
+                                                          method_num);
 
             let xform_self_ty = this.xform_self_ty(&m, new_trait_ref.substs());
 
@@ -432,7 +437,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     }
 
     fn assemble_extension_candidates_for_trait(&mut self,
-                                           trait_def_id: ast::DefId) {
+                                               trait_def_id: ast::DefId) {
         debug!("assemble_extension_candidates_for_trait: trait_def_id={}",
                trait_def_id.repr(self.tcx()));
 
@@ -984,6 +989,7 @@ fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                       -> Option<(uint, Rc<ty::Method<'tcx>>)>
 {
     let trait_items = ty::trait_items(tcx, trait_def_id);
+    debug!("trait_method; items: {}", trait_items);
     trait_items
         .iter()
         .filter(|item|
@@ -996,35 +1002,6 @@ fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
         .and_then(|(idx, item)| item.as_opt_method().map(|m| (idx, m)))
 }
 
-// Determine the index of a method in the list of all methods belonging
-// to a trait and its supertraits.
-fn get_method_index<'tcx>(tcx: &ty::ctxt<'tcx>,
-                          trait_ref: &ty::PolyTraitRef<'tcx>,
-                          subtrait: ty::PolyTraitRef<'tcx>,
-                          n_method: uint) -> uint {
-    // We need to figure the "real index" of the method in a
-    // listing of all the methods of an object. We do this by
-    // iterating down the supertraits of the object's trait until
-    // we find the trait the method came from, counting up the
-    // methods from them.
-    let mut method_count = n_method;
-    ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
-        if bound_ref.def_id() == trait_ref.def_id() {
-            false
-        } else {
-            let trait_items = ty::trait_items(tcx, bound_ref.def_id());
-            for trait_item in trait_items.iter() {
-                match *trait_item {
-                    ty::MethodTraitItem(_) => method_count += 1,
-                    ty::TypeTraitItem(_) => {}
-                }
-            }
-            true
-        }
-    });
-    method_count
-}
-
 impl<'tcx> Candidate<'tcx> {
     fn to_unadjusted_pick(&self) -> Pick<'tcx> {
         Pick {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d4e025a3813..19ec85dc61e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -507,9 +507,9 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
 impl<'a, 'tcx, 'v> Visitor<'v> for GatherLocalsVisitor<'a, 'tcx> {
     // Add explicitly-declared locals.
     fn visit_local(&mut self, local: &ast::Local) {
-        let o_ty = match local.ty.node {
-            ast::TyInfer => None,
-            _ => Some(self.fcx.to_ty(&*local.ty))
+        let o_ty = match local.ty {
+            Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
+            None => None
         };
         self.assign(local.span, local.id, o_ty);
         debug!("Local variable {} is assigned type {}",
diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs
index c85b542b6ca..1ef6c114032 100644
--- a/src/librustc_typeck/check/vtable.rs
+++ b/src/librustc_typeck/check/vtable.rs
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 use check::{FnCtxt, structurally_resolved_type};
-use middle::subst::{FnSpace, SelfSpace};
-use middle::traits;
+use middle::traits::{mod, ObjectSafetyViolation, MethodViolationCode};
 use middle::traits::{Obligation, ObligationCause};
 use middle::traits::report_fulfillment_errors;
 use middle::ty::{mod, Ty, AsPredicate};
@@ -133,217 +132,56 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
                                  object_trait: &ty::TyTrait<'tcx>,
                                  span: Span)
 {
-    // Also check that the type `object_trait` specifies all
-    // associated types for all supertraits.
-    let mut associated_types: FnvHashSet<(ast::DefId, ast::Name)> = FnvHashSet::new();
-
     let object_trait_ref =
         object_trait.principal_trait_ref_with_self_ty(tcx, tcx.types.err);
-    for tr in traits::supertraits(tcx, object_trait_ref.clone()) {
-        check_object_safety_inner(tcx, &tr, span);
-
-        let trait_def = ty::lookup_trait_def(tcx, object_trait_ref.def_id());
-        for &associated_type_name in trait_def.associated_type_names.iter() {
-            associated_types.insert((object_trait_ref.def_id(), associated_type_name));
-        }
-    }
 
-    for projection_bound in object_trait.bounds.projection_bounds.iter() {
-        let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
-                    projection_bound.0.projection_ty.item_name);
-        associated_types.remove(&pair);
+    if traits::is_object_safe(tcx, object_trait_ref.clone()) {
+        return;
     }
 
-    for (trait_def_id, name) in associated_types.into_iter() {
-        tcx.sess.span_err(
-            span,
-            format!("the value of the associated type `{}` (from the trait `{}`) must be specified",
-                    name.user_string(tcx),
-                    ty::item_path_str(tcx, trait_def_id)).as_slice());
-    }
-}
-
-fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                   object_trait: &ty::PolyTraitRef<'tcx>,
-                                   span: Span) {
-    let trait_items = ty::trait_items(tcx, object_trait.def_id());
-
-    let mut errors = Vec::new();
-    for item in trait_items.iter() {
-        match *item {
-            ty::MethodTraitItem(ref m) => {
-                errors.push(check_object_safety_of_method(tcx, object_trait, &**m))
+    span_err!(tcx.sess, span, E0038,
+              "cannot convert to a trait object because trait `{}` is not object-safe",
+              ty::item_path_str(tcx, object_trait_ref.def_id()));
+
+    let violations = traits::object_safety_violations(tcx, object_trait_ref.clone());
+    for violation in violations.into_iter() {
+        match violation {
+            ObjectSafetyViolation::SizedSelf => {
+                tcx.sess.span_note(
+                    span,
+                    "the trait cannot require that `Self : Sized`");
             }
-            ty::TypeTraitItem(_) => {}
-        }
-    }
-
-    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.def_id());
-        span_err!(tcx.sess, span, E0038,
-            "cannot convert to a trait object because trait `{}` is not object-safe",
-            trait_name);
-
-        for msg in errors {
-            tcx.sess.note(msg[]);
-        }
-    }
 
-    /// Returns a vec of error messages. If the vec is empty - no errors!
-    ///
-    /// There are some limitations to calling functions through an object, because (a) the self
-    /// type is not known (that's the whole point of a trait instance, after all, to obscure the
-    /// self type), (b) the call must go through a vtable and hence cannot be monomorphized and
-    /// (c) the trait contains static methods which can't be called because we don't know the
-    /// concrete type.
-    fn check_object_safety_of_method<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                           object_trait: &ty::PolyTraitRef<'tcx>,
-                                           method: &ty::Method<'tcx>)
-                                           -> Vec<String> {
-        let mut msgs = Vec::new();
-
-        let method_name = method.name.repr(tcx);
-
-        match method.explicit_self {
-            ty::ByValueExplicitSelfCategory => { // reason (a) above
-                msgs.push(format!("cannot call a method (`{}`) with a by-value \
-                                   receiver through a trait object", method_name))
+            ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => {
+                tcx.sess.span_note(
+                    span,
+                    format!("method `{}` has a receiver type of `Self`, \
+                             which cannot be used with a trait object",
+                            method.name.user_string(tcx)).as_slice());
             }
 
-            ty::StaticExplicitSelfCategory => {
-                // Static methods are never object safe (reason (c)).
-                msgs.push(format!("cannot call a static method (`{}`) \
-                                   through a trait object",
-                                  method_name));
-                return msgs;
+            ObjectSafetyViolation::Method(method, MethodViolationCode::StaticMethod) => {
+                tcx.sess.span_note(
+                    span,
+                    format!("method `{}` has no receiver",
+                            method.name.user_string(tcx)).as_slice());
             }
-            ty::ByReferenceExplicitSelfCategory(..) |
-            ty::ByBoxExplicitSelfCategory => {}
-        }
 
-        // reason (a) above
-        let check_for_self_ty = |&: ty| {
-            if contains_illegal_self_type_reference(tcx, object_trait.def_id(), ty) {
-                Some(format!(
-                    "cannot call a method (`{}`) whose type contains \
-                     a self-type (`{}`) through a trait object",
-                    method_name, ty.user_string(tcx)))
-            } else {
-                None
-            }
-        };
-        let ref sig = method.fty.sig;
-        for &input_ty in sig.0.inputs[1..].iter() {
-            if let Some(msg) = check_for_self_ty(input_ty) {
-                msgs.push(msg);
-            }
-        }
-        if let ty::FnConverging(result_type) = sig.0.output {
-            if let Some(msg) = check_for_self_ty(result_type) {
-                msgs.push(msg);
+            ObjectSafetyViolation::Method(method, MethodViolationCode::ReferencesSelf) => {
+                tcx.sess.span_note(
+                    span,
+                    format!("method `{}` references the `Self` type \
+                             in its arguments or return type",
+                            method.name.user_string(tcx)).as_slice());
             }
-        }
-
-        if method.generics.has_type_params(FnSpace) {
-            // reason (b) above
-            msgs.push(format!("cannot call a generic method (`{}`) through a trait object",
-                              method_name));
-        }
-
-        msgs
-    }
 
-    fn contains_illegal_self_type_reference<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                                  trait_def_id: ast::DefId,
-                                                  ty: Ty<'tcx>)
-                                                  -> bool
-    {
-        // This is somewhat subtle. In general, we want to forbid
-        // references to `Self` in the argument and return types,
-        // since the value of `Self` is erased. However, there is one
-        // exception: it is ok to reference `Self` in order to access
-        // an associated type of the current trait, since we retain
-        // the value of those associated types in the object type
-        // itself.
-        //
-        // ```rust
-        // trait SuperTrait {
-        //     type X;
-        // }
-        //
-        // trait Trait : SuperTrait {
-        //     type Y;
-        //     fn foo(&self, x: Self) // bad
-        //     fn foo(&self) -> Self // bad
-        //     fn foo(&self) -> Option<Self> // bad
-        //     fn foo(&self) -> Self::Y // OK, desugars to next example
-        //     fn foo(&self) -> <Self as Trait>::Y // OK
-        //     fn foo(&self) -> Self::X // OK, desugars to next example
-        //     fn foo(&self) -> <Self as SuperTrait>::X // OK
-        // }
-        // ```
-        //
-        // However, it is not as simple as allowing `Self` in a projected
-        // type, because there are illegal ways to use `Self` as well:
-        //
-        // ```rust
-        // trait Trait : SuperTrait {
-        //     ...
-        //     fn foo(&self) -> <Self as SomeOtherTrait>::X;
-        // }
-        // ```
-        //
-        // Here we will not have the type of `X` recorded in the
-        // object type, and we cannot resolve `Self as SomeOtherTrait`
-        // without knowing what `Self` is.
-
-        let mut supertraits: Option<Vec<ty::PolyTraitRef<'tcx>>> = None;
-        let mut error = false;
-        ty::maybe_walk_ty(ty, |ty| {
-            match ty.sty {
-                ty::ty_param(ref param_ty) => {
-                    if param_ty.space == SelfSpace {
-                        error = true;
-                    }
-
-                    false // no contained types to walk
-                }
-
-                ty::ty_projection(ref data) => {
-                    // This is a projected type `<Foo as SomeTrait>::X`.
-
-                    // Compute supertraits of current trait lazilly.
-                    if supertraits.is_none() {
-                        let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
-                        let trait_ref = ty::Binder(trait_def.trait_ref.clone());
-                        supertraits = Some(traits::supertraits(tcx, trait_ref).collect());
-                    }
-
-                    // Determine whether the trait reference `Foo as
-                    // SomeTrait` is in fact a supertrait of the
-                    // current trait. In that case, this type is
-                    // legal, because the type `X` will be specified
-                    // in the object type.  Note that we can just use
-                    // direct equality here because all of these types
-                    // are part of the formal parameter listing, and
-                    // hence there should be no inference variables.
-                    let projection_trait_ref = ty::Binder(data.trait_ref.clone());
-                    let is_supertrait_of_current_trait =
-                        supertraits.as_ref().unwrap().contains(&projection_trait_ref);
-
-                    if is_supertrait_of_current_trait {
-                        false // do not walk contained types, do not report error, do collect $200
-                    } else {
-                        true // DO walk contained types, POSSIBLY reporting an error
-                    }
-                }
-
-                _ => true, // walk contained types, if any
+            ObjectSafetyViolation::Method(method, MethodViolationCode::Generic) => {
+                tcx.sess.span_note(
+                    span,
+                    format!("method `{}` has generic type parameters",
+                            method.name.user_string(tcx)).as_slice());
             }
-        });
-
-        error
+        }
     }
 }
 
@@ -392,7 +230,7 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             cause.clone());
     }
 
-    // Finally, create obligations for the projection predicates.
+    // Create obligations for the projection predicates.
     let projection_bounds =
         object_trait.projection_bounds_with_self_ty(fcx.tcx(), referent_ty);
     for projection_bound in projection_bounds.iter() {
@@ -401,9 +239,47 @@ pub fn register_object_cast_obligations<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         fcx.register_predicate(projection_obligation);
     }
 
+    // Finally, check that there IS a projection predicate for every associated type.
+    check_object_type_binds_all_associated_types(fcx.tcx(),
+                                                 span,
+                                                 object_trait);
+
     object_trait_ref
 }
 
+fn check_object_type_binds_all_associated_types<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                                      span: Span,
+                                                      object_trait: &ty::TyTrait<'tcx>)
+{
+    let object_trait_ref =
+        object_trait.principal_trait_ref_with_self_ty(tcx, tcx.types.err);
+
+    let mut associated_types: FnvHashSet<(ast::DefId, ast::Name)> =
+        traits::supertraits(tcx, object_trait_ref.clone())
+        .flat_map(|tr| {
+            let trait_def = ty::lookup_trait_def(tcx, tr.def_id());
+            trait_def.associated_type_names
+                .clone()
+                .into_iter()
+                .map(move |associated_type_name| (tr.def_id(), associated_type_name))
+        })
+        .collect();
+
+    for projection_bound in object_trait.bounds.projection_bounds.iter() {
+        let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
+                    projection_bound.0.projection_ty.item_name);
+        associated_types.remove(&pair);
+    }
+
+    for (trait_def_id, name) in associated_types.into_iter() {
+        tcx.sess.span_err(
+            span,
+            format!("the value of the associated type `{}` (from the trait `{}`) must be specified",
+                    name.user_string(tcx),
+                    ty::item_path_str(tcx, trait_def_id)).as_slice());
+    }
+}
+
 pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
     debug!("select_all_fcx_obligations_or_error");
 
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index 79443200ddf..1da49799712 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -18,7 +18,7 @@ use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
 use syntax::visit;
-use util::ppaux::Repr;
+use util::ppaux::{Repr, UserString};
 
 pub fn check(tcx: &ty::ctxt) {
     let mut orphan = OrphanChecker { tcx: tcx };
@@ -57,6 +57,11 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
                     ty::ty_trait(ref data) => {
                         self.check_def_id(item.span, data.principal_def_id());
                     }
+                    ty::ty_uniq(..) => {
+                        self.check_def_id(item.span,
+                                          self.tcx.lang_items.owned_box()
+                                              .unwrap());
+                    }
                     _ => {
                         span_err!(self.tcx.sess, item.span, E0118,
                                   "no base type found for inherent implementation; \
@@ -67,10 +72,27 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
             ast::ItemImpl(_, _, Some(_), _, _) => {
                 // "Trait" impl
                 debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
-                if traits::is_orphan_impl(self.tcx, def_id) {
-                    span_err!(self.tcx.sess, item.span, E0117,
-                              "cannot provide an extension implementation \
-                               where both trait and type are not defined in this crate");
+                match traits::orphan_check(self.tcx, def_id) {
+                    Ok(()) => { }
+                    Err(traits::OrphanCheckErr::NoLocalInputType) => {
+                        span_err!(self.tcx.sess, item.span, E0117,
+                                  "cannot provide an extension implementation \
+                                   where both trait and type are not defined in this crate");
+                    }
+                    Err(traits::OrphanCheckErr::UncoveredTypeParameter(param_ty)) => {
+                        if !self.tcx.sess.features.borrow().old_orphan_check {
+                            self.tcx.sess.span_err(
+                                item.span,
+                                format!("type parameter `{}` must also appear as a type parameter \
+                                         of some type defined within this crate",
+                                        param_ty.user_string(self.tcx)).as_slice());
+                            self.tcx.sess.span_note(
+                                item.span,
+                                format!("for a limited time, you can add \
+                                         `#![feature(old_orphan_check)]` to your crate \
+                                         to disable this rule").as_slice());
+                        }
+                    }
                 }
             }
             _ => {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 9e184db3b84..fe61b3de2cf 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -843,6 +843,7 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let bounds = compute_bounds(ccx,
                                 self_param_ty.to_ty(ccx.tcx),
                                 bounds.as_slice(),
+                                SizedByDefault::No,
                                 it.span);
 
     let associated_type_names: Vec<_> =
@@ -1098,6 +1099,7 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                 let bounds = compute_bounds(ccx,
                                             assoc_ty,
                                             assoc_type_def.bounds.as_slice(),
+                                            SizedByDefault::Yes,
                                             assoc_type_def.span);
 
                 ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter()
@@ -1306,6 +1308,7 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
     let bounds = compute_bounds(this,
                                 param_ty.to_ty(this.tcx()),
                                 param.bounds[],
+                                SizedByDefault::Yes,
                                 param.span);
     let default = match param.default {
         None => None,
@@ -1342,29 +1345,35 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
     def
 }
 
+enum SizedByDefault { Yes, No }
+
 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
 /// built-in trait (formerly known as kind): Send.
 fn compute_bounds<'tcx,AC>(this: &AC,
                            param_ty: ty::Ty<'tcx>,
                            ast_bounds: &[ast::TyParamBound],
+                           sized_by_default: SizedByDefault,
                            span: Span)
                            -> ty::ParamBounds<'tcx>
-                           where AC: AstConv<'tcx> {
+                           where AC: AstConv<'tcx>
+{
     let mut param_bounds = conv_param_bounds(this,
                                              span,
                                              param_ty,
                                              ast_bounds);
 
-    add_unsized_bound(this,
-                      &mut param_bounds.builtin_bounds,
-                      ast_bounds,
-                      span);
+    if let SizedByDefault::Yes = sized_by_default {
+        add_unsized_bound(this,
+                          &mut param_bounds.builtin_bounds,
+                          ast_bounds,
+                          span);
 
-    check_bounds_compatible(this.tcx(),
-                            param_ty,
-                            &param_bounds,
-                            span);
+        check_bounds_compatible(this.tcx(),
+                                param_ty,
+                                &param_bounds,
+                                span);
+    }
 
     param_bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
 
diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs
index a89b20c949b..0f0dbf6a24d 100644
--- a/src/librustdoc/flock.rs
+++ b/src/librustdoc/flock.rs
@@ -18,10 +18,10 @@
 
 pub use self::imp::Lock;
 
-
 #[cfg(unix)]
 mod imp {
     use libc;
+    use std::c_str::ToCStr;
 
     #[cfg(target_os = "linux")]
     mod os {
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 5623c0f0e53..4f277cc868a 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -12,7 +12,7 @@ use clean::*;
 use std::iter::Extend;
 use std::mem::{replace, swap};
 
-pub trait DocFolder {
+pub trait DocFolder : Sized {
     fn fold_item(&mut self, item: Item) -> Option<Item> {
         self.fold_item_recur(item)
     }
diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs
index fe93dbbc081..b4afb67170b 100644
--- a/src/librustdoc/html/escape.rs
+++ b/src/librustdoc/html/escape.rs
@@ -29,7 +29,7 @@ impl<'a> fmt::Show for Escape<'a> {
         for (i, ch) in s.bytes().enumerate() {
             match ch as char {
                 '<' | '>' | '&' | '\'' | '"' => {
-                    try!(fmt.write(pile_o_bits.slice(last, i).as_bytes()));
+                    try!(fmt.write_str(pile_o_bits.slice(last, i)));
                     let s = match ch as char {
                         '>' => "&gt;",
                         '<' => "&lt;",
@@ -38,7 +38,7 @@ impl<'a> fmt::Show for Escape<'a> {
                         '"' => "&quot;",
                         _ => unreachable!()
                     };
-                    try!(fmt.write(s.as_bytes()));
+                    try!(fmt.write_str(s));
                     last = i + 1;
                 }
                 _ => {}
@@ -46,7 +46,7 @@ impl<'a> fmt::Show for Escape<'a> {
         }
 
         if last < s.len() {
-            try!(fmt.write(pile_o_bits.slice_from(last).as_bytes()));
+            try!(fmt.write_str(pile_o_bits.slice_from(last)));
         }
         Ok(())
     }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 3c09a10f3d9..36619566f8c 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -69,7 +69,7 @@ impl<'a> fmt::Show for TyParamBounds<'a> {
         let &TyParamBounds(bounds) = self;
         for (i, bound) in bounds.iter().enumerate() {
             if i > 0 {
-                try!(f.write(" + ".as_bytes()));
+                try!(f.write_str(" + "));
             }
             try!(write!(f, "{}", *bound));
         }
@@ -80,24 +80,24 @@ impl<'a> fmt::Show for TyParamBounds<'a> {
 impl fmt::Show for clean::Generics {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if self.lifetimes.len() == 0 && self.type_params.len() == 0 { return Ok(()) }
-        try!(f.write("&lt;".as_bytes()));
+        try!(f.write_str("&lt;"));
 
         for (i, life) in self.lifetimes.iter().enumerate() {
             if i > 0 {
-                try!(f.write(", ".as_bytes()));
+                try!(f.write_str(", "));
             }
             try!(write!(f, "{}", *life));
         }
 
         if self.type_params.len() > 0 {
             if self.lifetimes.len() > 0 {
-                try!(f.write(", ".as_bytes()));
+                try!(f.write_str(", "));
             }
             for (i, tp) in self.type_params.iter().enumerate() {
                 if i > 0 {
-                    try!(f.write(", ".as_bytes()))
+                    try!(f.write_str(", "))
                 }
-                try!(f.write(tp.name.as_bytes()));
+                try!(f.write_str(tp.name[]));
 
                 if tp.bounds.len() > 0 {
                     try!(write!(f, ": {}", TyParamBounds(tp.bounds.as_slice())));
@@ -109,7 +109,7 @@ impl fmt::Show for clean::Generics {
                 };
             }
         }
-        try!(f.write("&gt;".as_bytes()));
+        try!(f.write_str("&gt;"));
         Ok(())
     }
 }
@@ -120,10 +120,10 @@ impl<'a> fmt::Show for WhereClause<'a> {
         if gens.where_predicates.len() == 0 {
             return Ok(());
         }
-        try!(f.write(" <span class='where'>where ".as_bytes()));
+        try!(f.write_str(" <span class='where'>where "));
         for (i, pred) in gens.where_predicates.iter().enumerate() {
             if i > 0 {
-                try!(f.write(", ".as_bytes()));
+                try!(f.write_str(", "));
             }
             match pred {
                 &clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
@@ -135,7 +135,7 @@ impl<'a> fmt::Show for WhereClause<'a> {
                     try!(write!(f, "{}: ", lifetime));
                     for (i, lifetime) in bounds.iter().enumerate() {
                         if i > 0 {
-                            try!(f.write(" + ".as_bytes()));
+                            try!(f.write_str(" + "));
                         }
 
                         try!(write!(f, "{}", lifetime));
@@ -146,14 +146,14 @@ impl<'a> fmt::Show for WhereClause<'a> {
                 }
             }
         }
-        try!(f.write("</span>".as_bytes()));
+        try!(f.write_str("</span>"));
         Ok(())
     }
 }
 
 impl fmt::Show for clean::Lifetime {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(f.write(self.get_ref().as_bytes()));
+        try!(f.write_str(self.get_ref()));
         Ok(())
     }
 }
@@ -161,14 +161,14 @@ impl fmt::Show for clean::Lifetime {
 impl fmt::Show for clean::PolyTrait {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if self.lifetimes.len() > 0 {
-            try!(f.write("for&lt;".as_bytes()));
+            try!(f.write_str("for&lt;"));
             for (i, lt) in self.lifetimes.iter().enumerate() {
                 if i > 0 {
-                    try!(f.write(", ".as_bytes()));
+                    try!(f.write_str(", "));
                 }
                 try!(write!(f, "{}", lt));
             }
-            try!(f.write("&gt; ".as_bytes()));
+            try!(f.write_str("&gt; "));
         }
         write!(f, "{}", self.trait_)
     }
@@ -196,38 +196,38 @@ impl fmt::Show for clean::PathParameters {
         match *self {
             clean::PathParameters::AngleBracketed { ref lifetimes, ref types } => {
                 if lifetimes.len() > 0 || types.len() > 0 {
-                    try!(f.write("&lt;".as_bytes()));
+                    try!(f.write_str("&lt;"));
                     let mut comma = false;
                     for lifetime in lifetimes.iter() {
                         if comma {
-                            try!(f.write(", ".as_bytes()));
+                            try!(f.write_str(", "));
                         }
                         comma = true;
                         try!(write!(f, "{}", *lifetime));
                     }
                     for ty in types.iter() {
                         if comma {
-                            try!(f.write(", ".as_bytes()));
+                            try!(f.write_str(", "));
                         }
                         comma = true;
                         try!(write!(f, "{}", *ty));
                     }
-                    try!(f.write("&gt;".as_bytes()));
+                    try!(f.write_str("&gt;"));
                 }
             }
             clean::PathParameters::Parenthesized { ref inputs, ref output } => {
-                try!(f.write("(".as_bytes()));
+                try!(f.write_str("("));
                 let mut comma = false;
                 for ty in inputs.iter() {
                     if comma {
-                        try!(f.write(", ".as_bytes()));
+                        try!(f.write_str(", "));
                     }
                     comma = true;
                     try!(write!(f, "{}", *ty));
                 }
-                try!(f.write(")".as_bytes()));
+                try!(f.write_str(")"));
                 if let Some(ref ty) = *output {
-                    try!(f.write(" -&gt; ".as_bytes()));
+                    try!(f.write_str(" -&gt; "));
                     try!(write!(f, "{}", ty));
                 }
             }
@@ -238,7 +238,7 @@ impl fmt::Show for clean::PathParameters {
 
 impl fmt::Show for clean::PathSegment {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(f.write(self.name.as_bytes()));
+        try!(f.write_str(self.name.as_slice()));
         write!(f, "{}", self.params)
     }
 }
@@ -246,12 +246,12 @@ impl fmt::Show for clean::PathSegment {
 impl fmt::Show for clean::Path {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if self.global {
-            try!(f.write("::".as_bytes()))
+            try!(f.write_str("::"))
         }
 
         for (i, seg) in self.segments.iter().enumerate() {
             if i > 0 {
-                try!(f.write("::".as_bytes()))
+                try!(f.write_str("::"))
             }
             try!(write!(f, "{}", seg));
         }
@@ -433,10 +433,10 @@ impl fmt::Show for clean::Type {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             clean::TyParamBinder(id) => {
-                f.write(cache().typarams[ast_util::local_def(id)].as_bytes())
+                f.write_str(cache().typarams[ast_util::local_def(id)][])
             }
             clean::Generic(ref name) => {
-                f.write(name.as_bytes())
+                f.write_str(name.as_slice())
             }
             clean::ResolvedPath{ did, ref typarams, ref path } => {
                 try!(resolved_path(f, did, path, false));
@@ -522,7 +522,7 @@ impl fmt::Show for clean::Type {
                 primitive_link(f, clean::Slice,
                                format!("[{}, ..{}]", **t, *s).as_slice())
             }
-            clean::Bottom => f.write("!".as_bytes()),
+            clean::Bottom => f.write_str("!"),
             clean::RawPointer(m, ref t) => {
                 write!(f, "*{}{}", RawMutableSpace(m), **t)
             }
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 2c05524ea7f..1fce5d59698 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -29,11 +29,12 @@
 
 use libc;
 use std::ascii::AsciiExt;
+use std::c_str::ToCStr;
 use std::cell::{RefCell, Cell};
+use std::collections::HashMap;
 use std::fmt;
 use std::slice;
 use std::str;
-use std::collections::HashMap;
 
 use html::toc::TocBuilder;
 use html::highlight;
@@ -302,7 +303,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
 
         if ret.is_ok() {
             let buf = slice::from_raw_buf(&(*ob).data, (*ob).size as uint);
-            ret = w.write(buf);
+            ret = w.write_str(str::from_utf8(buf).unwrap());
         }
         hoedown_buffer_free(ob);
         ret
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index f8a0b88b408..0cfc1042ae6 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -35,6 +35,7 @@
 pub use self::ExternalLocation::*;
 
 use std::cell::RefCell;
+use std::cmp::Ordering::{mod, Less, Greater, Equal};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::collections::{HashMap, HashSet};
 use std::default::Default;
@@ -49,7 +50,6 @@ use std::sync::Arc;
 use externalfiles::ExternalHtml;
 
 use serialize::json;
-use serialize::Encodable;
 use serialize::json::ToJson;
 use syntax::ast;
 use syntax::ast_util;
@@ -1095,7 +1095,7 @@ impl Context {
         try!(self.recurse(stability.name.clone(), |this| {
             let json_dst = &this.dst.join("stability.json");
             let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
-            try!(stability.encode(&mut json::Encoder::new(&mut json_out)));
+            try!(write!(&mut json_out, "{}", json::as_json(&stability)));
 
             let mut title = stability.name.clone();
             title.push_str(" - Stability dashboard");
@@ -1311,7 +1311,8 @@ impl<'a> Item<'a> {
         // has anchors for the line numbers that we're linking to.
         if ast_util::is_local(self.item.def_id) {
             let mut path = Vec::new();
-            clean_srcpath(&cx.src_root, self.item.source.filename.as_bytes(), |component| {
+            clean_srcpath(&cx.src_root, self.item.source.filename.as_bytes(),
+                          |component| {
                 path.push(component.to_string());
             });
             let href = if self.item.source.loline == self.item.source.hiline {
@@ -1713,7 +1714,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
             try!(write!(w, ";\n"));
         }
         if types.len() > 0 && required.len() > 0 {
-            try!(w.write("\n".as_bytes()));
+            try!(w.write_str("\n"));
         }
         for m in required.iter() {
             try!(write!(w, "    "));
@@ -1721,7 +1722,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
             try!(write!(w, ";\n"));
         }
         if required.len() > 0 && provided.len() > 0 {
-            try!(w.write("\n".as_bytes()));
+            try!(w.write_str("\n"));
         }
         for m in provided.iter() {
             try!(write!(w, "    "));
@@ -1811,6 +1812,18 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     Ok(())
 }
 
+fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
+              typ: &clean::TyParam) -> fmt::Result {
+    try!(write!(w, "type {}", it.name.as_ref().unwrap()));
+    if typ.bounds.len() > 0 {
+        try!(write!(w, ": {}", TyParamBounds(&*typ.bounds)))
+    }
+    if let Some(ref default) = typ.default {
+        try!(write!(w, " = {}", default));
+    }
+    Ok(())
+}
+
 fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
     fn method(w: &mut fmt::Formatter, it: &clean::Item, unsafety: ast::Unsafety,
            g: &clean::Generics, selfty: &clean::SelfTy,
@@ -1827,17 +1840,6 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
                decl = Method(selfty, d),
                where_clause = WhereClause(g))
     }
-    fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
-                  typ: &clean::TyParam) -> fmt::Result {
-        try!(write!(w, "type {}", it.name.as_ref().unwrap()));
-        if typ.bounds.len() > 0 {
-            try!(write!(w, ": {}", TyParamBounds(&*typ.bounds)))
-        }
-        if let Some(ref default) = typ.default {
-            try!(write!(w, " = {}", default));
-        }
-        Ok(())
-    }
     match meth.inner {
         clean::TyMethodItem(ref m) => {
             method(w, meth, m.unsafety, &m.generics, &m.self_, &m.decl)
@@ -2122,6 +2124,15 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
                 try!(write!(w, "type {} = {}", name, tydef.type_));
                 try!(write!(w, "</code></h4>\n"));
             }
+            clean::AssociatedTypeItem(ref typaram) => {
+                let name = item.name.as_ref().unwrap();
+                try!(write!(w, "<h4 id='assoc_type.{}' class='{}'>{}<code>",
+                            *name,
+                            shortty(item),
+                            ConciseStability(&item.stability)));
+                try!(assoc_type(w, item, typaram));
+                try!(write!(w, "</code></h4>\n"));
+            }
             _ => panic!("can't make docs for trait item with name {}", item.name)
         }
         match item.doc_value() {
@@ -2260,8 +2271,9 @@ impl<'a> fmt::Show for Source<'a> {
 
 fn item_macro(w: &mut fmt::Formatter, it: &clean::Item,
               t: &clean::Macro) -> fmt::Result {
-    try!(w.write(highlight::highlight(t.source.as_slice(), Some("macro"),
-                                      None).as_bytes()));
+    try!(w.write_str(highlight::highlight(t.source.as_slice(),
+                                          Some("macro"),
+                                          None)[]));
     document(w, it)
 }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index ccdc8164255..1beeeaf629d 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -20,6 +20,7 @@
 #![allow(unknown_features)]
 #![feature(globs, macro_rules, phase, slicing_syntax)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
 
 extern crate arena;
 extern crate getopts;
@@ -41,7 +42,7 @@ use std::io::File;
 use std::io;
 use std::rc::Rc;
 use externalfiles::ExternalHtml;
-use serialize::{Decodable, Encodable};
+use serialize::Decodable;
 use serialize::json::{mod, Json};
 use rustc::session::search_paths::SearchPaths;
 
@@ -493,14 +494,7 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
 
     // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
     // straight to the Rust JSON representation.
-    let crate_json_str = {
-        let mut w = Vec::new();
-        {
-            let mut encoder = json::Encoder::new(&mut w as &mut io::Writer);
-            krate.encode(&mut encoder).unwrap();
-        }
-        String::from_utf8(w).unwrap()
-    };
+    let crate_json_str = format!("{}", json::as_json(&krate));
     let crate_json = match json::from_str(crate_json_str.as_slice()) {
         Ok(j) => j,
         Err(e) => panic!("Rust generated JSON is invalid: {}", e)
@@ -510,5 +504,5 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
     json.insert("plugins".to_string(), Json::Object(plugins_json));
 
     let mut file = try!(File::create(&dst));
-    Json::Object(json).to_writer(&mut file)
+    write!(&mut file, "{}", Json::Object(json))
 }
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 2e3adf8e767..058a7acd455 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -13,8 +13,9 @@
 //! hierarchy, with item counts for every stability level per module. A parent
 //! module's count includes its children's.
 
-use std::ops::Add;
+use std::cmp::Ordering;
 use std::num::Zero;
+use std::ops::Add;
 
 use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
 use syntax::ast::Public;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index ba66c51b8fc..743c8b240d1 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 use std::cell::RefCell;
+use std::sync::mpsc::channel;
 use std::dynamic_lib::DynamicLibrary;
 use std::io::{Command, TempDir};
 use std::io;
 use std::os;
 use std::str;
-use std::string::String;
-use std::thunk::Thunk;
 use std::thread::Thread;
+use std::thunk::Thunk;
 
 use std::collections::{HashSet, HashMap};
 use testing;
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 8a9c2eebf3a..a87044bb3b3 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -76,12 +76,13 @@
 //! Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the
 //! serialization API, using the derived serialization code.
 //!
-//! ```rust
+//! ```notrust
+//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment
 //! extern crate serialize;
 //! use serialize::json;
 //!
 //! // Automatically generate `Decodable` and `Encodable` trait implementations
-//! #[deriving(Decodable, Encodable)]
+//! #[deriving(RustcDecodable, RustcEncodable)]
 //! pub struct TestStruct  {
 //!     data_int: u8,
 //!     data_str: String,
@@ -110,7 +111,8 @@
 //!
 //! ### Simple example of `ToJson` usage
 //!
-//! ```rust
+//! ```notrust
+//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment
 //! extern crate serialize;
 //! use serialize::json::{mod, ToJson, Json};
 //!
@@ -149,7 +151,8 @@
 //!
 //! ### Verbose example of `ToJson` usage
 //!
-//! ```rust
+//! ```notrust
+//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment
 //! extern crate serialize;
 //! use std::collections::BTreeMap;
 //! use serialize::json::{mod, Json, ToJson};
@@ -227,6 +230,11 @@ pub enum Json {
 pub type Array = Vec<Json>;
 pub type Object = BTreeMap<string::String, Json>;
 
+pub struct PrettyJson<'a> { inner: &'a Json }
+
+pub struct AsJson<'a, T: 'a> { inner: &'a T }
+pub struct AsPrettyJson<'a, T: 'a> { inner: &'a T, indent: Option<uint> }
+
 /// The errors that can arise while parsing a JSON stream.
 #[deriving(Clone, Copy, PartialEq)]
 pub enum ErrorCode {
@@ -303,9 +311,15 @@ pub fn decode<T: ::Decodable<Decoder, DecoderError>>(s: &str) -> DecodeResult<T>
 }
 
 /// Shortcut function to encode a `T` into a JSON `String`
-pub fn encode<'a, T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> string::String {
-    let buff = Encoder::buffer_encode(object);
-    string::String::from_utf8(buff).unwrap()
+pub fn encode<T>(object: &T) -> string::String
+                 where T: for<'a> Encodable<Encoder<'a>, fmt::Error>
+{
+    let mut s = String::new();
+    {
+        let mut encoder = Encoder::new(&mut s);
+        let _ = object.encode(&mut encoder);
+    }
+    s
 }
 
 impl fmt::Show for ErrorCode {
@@ -323,16 +337,16 @@ impl std::error::Error for DecoderError {
     fn detail(&self) -> Option<std::string::String> { Some(self.to_string()) }
 }
 
-pub type EncodeResult = io::IoResult<()>;
+pub type EncodeResult = fmt::Result;
 pub type DecodeResult<T> = Result<T, DecoderError>;
 
-pub fn escape_bytes(wr: &mut io::Writer, bytes: &[u8]) -> Result<(), io::IoError> {
+fn escape_str(wr: &mut fmt::Writer, v: &str) -> fmt::Result {
     try!(wr.write_str("\""));
 
     let mut start = 0;
 
-    for (i, byte) in bytes.iter().enumerate() {
-        let escaped = match *byte {
+    for (i, byte) in v.bytes().enumerate() {
+        let escaped = match byte {
             b'"' => "\\\"",
             b'\\' => "\\\\",
             b'\x00' => "\\u0000",
@@ -372,7 +386,7 @@ pub fn escape_bytes(wr: &mut io::Writer, bytes: &[u8]) -> Result<(), io::IoError
         };
 
         if start < i {
-            try!(wr.write(bytes[start..i]));
+            try!(wr.write_str(v[start..i]));
         }
 
         try!(wr.write_str(escaped));
@@ -380,34 +394,30 @@ pub fn escape_bytes(wr: &mut io::Writer, bytes: &[u8]) -> Result<(), io::IoError
         start = i + 1;
     }
 
-    if start != bytes.len() {
-        try!(wr.write(bytes[start..]));
+    if start != v.len() {
+        try!(wr.write_str(v[start..]));
     }
 
     wr.write_str("\"")
 }
 
-fn escape_str(writer: &mut io::Writer, v: &str) -> Result<(), io::IoError> {
-    escape_bytes(writer, v.as_bytes())
-}
-
-fn escape_char(writer: &mut io::Writer, v: char) -> Result<(), io::IoError> {
+fn escape_char(writer: &mut fmt::Writer, v: char) -> fmt::Result {
     let mut buf = [0; 4];
-    let len = v.encode_utf8(&mut buf).unwrap();
-    escape_bytes(writer, buf[mut ..len])
+    let n = v.encode_utf8(&mut buf).unwrap();
+    let buf = unsafe { str::from_utf8_unchecked(buf[0..n]) };
+    escape_str(writer, buf)
 }
 
-fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> {
-    const LEN: uint = 16;
-    static BUF: [u8; LEN] = [b' '; LEN];
+fn spaces(wr: &mut fmt::Writer, mut n: uint) -> fmt::Result {
+    const BUF: &'static str = "                ";
 
-    while n >= LEN {
-        try!(wr.write(&BUF));
-        n -= LEN;
+    while n >= BUF.len() {
+        try!(wr.write_str(BUF));
+        n -= BUF.len();
     }
 
     if n > 0 {
-        wr.write(BUF[..n])
+        wr.write_str(BUF[..n])
     } else {
         Ok(())
     }
@@ -423,31 +433,18 @@ fn fmt_number_or_null(v: f64) -> string::String {
 
 /// A structure for implementing serialization to JSON.
 pub struct Encoder<'a> {
-    writer: &'a mut (io::Writer+'a),
+    writer: &'a mut (fmt::Writer+'a),
 }
 
 impl<'a> Encoder<'a> {
     /// Creates a new JSON encoder whose output will be written to the writer
     /// specified.
-    pub fn new(writer: &'a mut io::Writer) -> Encoder<'a> {
+    pub fn new(writer: &'a mut fmt::Writer) -> Encoder<'a> {
         Encoder { writer: writer }
     }
-
-    /// Encode the specified struct into a json [u8]
-    pub fn buffer_encode<T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> Vec<u8>  {
-        //Serialize the object in a string using a writer
-        let mut m = Vec::new();
-        // FIXME(14302) remove the transmute and unsafe block.
-        unsafe {
-            let mut encoder = Encoder::new(&mut m as &mut io::Writer);
-            // Vec<u8> never Errs
-            let _ = object.encode(transmute(&mut encoder));
-        }
-        m
-    }
 }
 
-impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
+impl<'a> ::Encoder<fmt::Error> for Encoder<'a> {
     fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
 
     fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
@@ -646,14 +643,14 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
 /// Another encoder for JSON, but prints out human-readable JSON instead of
 /// compact data
 pub struct PrettyEncoder<'a> {
-    writer: &'a mut (io::Writer+'a),
+    writer: &'a mut (fmt::Writer+'a),
     curr_indent: uint,
     indent: uint,
 }
 
 impl<'a> PrettyEncoder<'a> {
     /// Creates a new encoder whose output will be written to the specified writer
-    pub fn new(writer: &'a mut io::Writer) -> PrettyEncoder<'a> {
+    pub fn new(writer: &'a mut fmt::Writer) -> PrettyEncoder<'a> {
         PrettyEncoder { writer: writer, curr_indent: 0, indent: 2, }
     }
 
@@ -667,7 +664,7 @@ impl<'a> PrettyEncoder<'a> {
     }
 }
 
-impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
+impl<'a> ::Encoder<fmt::Error> for PrettyEncoder<'a> {
     fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
 
     fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
@@ -927,25 +924,23 @@ impl<E: ::Encoder<S>, S> Encodable<E, S> for Json {
     }
 }
 
-impl Json {
-    /// Encodes a json value into an io::writer. Uses a single line.
-    pub fn to_writer(&self, writer: &mut io::Writer) -> EncodeResult {
-        let mut encoder = Encoder::new(writer);
-        self.encode(&mut encoder)
-    }
+/// Create an `AsJson` wrapper which can be used to print a value as JSON
+/// on-the-fly via `write!`
+pub fn as_json<T>(t: &T) -> AsJson<T> {
+    AsJson { inner: t }
+}
 
-    /// Encodes a json value into an io::writer.
-    /// Pretty-prints in a more readable format.
-    pub fn to_pretty_writer(&self, writer: &mut io::Writer) -> EncodeResult {
-        let mut encoder = PrettyEncoder::new(writer);
-        self.encode(&mut encoder)
-    }
+/// Create an `AsPrettyJson` wrapper which can be used to print a value as JSON
+/// on-the-fly via `write!`
+pub fn as_pretty_json<T>(t: &T) -> AsPrettyJson<T> {
+    AsPrettyJson { inner: t, indent: None }
+}
 
-    /// Encodes a json value into a string
-    pub fn to_pretty_str(&self) -> string::String {
-        let mut s = Vec::new();
-        self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
-        string::String::from_utf8(s).unwrap()
+impl Json {
+    /// Borrow this json object as a pretty object to generate a pretty
+    /// representation for it via `Show`.
+    pub fn pretty(&self) -> PrettyJson {
+        PrettyJson { inner: self }
     }
 
      /// If the Json value is an Object, returns the value associated with the provided key.
@@ -2424,10 +2419,65 @@ impl<A:ToJson> ToJson for Option<A> {
     }
 }
 
+struct FormatShim<'a, 'b: 'a> {
+    inner: &'a mut fmt::Formatter<'b>,
+}
+
+impl<'a, 'b> fmt::Writer for FormatShim<'a, 'b> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        self.inner.write_str(s)
+    }
+}
+
 impl fmt::Show for Json {
     /// Encodes a json value into a string
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.to_writer(f).map_err(|_| fmt::Error)
+        let mut shim = FormatShim { inner: f };
+        let mut encoder = Encoder::new(&mut shim);
+        self.encode(&mut encoder)
+    }
+}
+
+impl<'a> fmt::Show for PrettyJson<'a> {
+    /// Encodes a json value into a string
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut shim = FormatShim { inner: f };
+        let mut encoder = PrettyEncoder::new(&mut shim);
+        self.inner.encode(&mut encoder)
+    }
+}
+
+impl<'a, T> fmt::Show for AsJson<'a, T>
+    where T: for<'b> Encodable<Encoder<'b>, fmt::Error>
+{
+    /// Encodes a json value into a string
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut shim = FormatShim { inner: f };
+        let mut encoder = Encoder::new(&mut shim);
+        self.inner.encode(&mut encoder)
+    }
+}
+
+impl<'a, T> AsPrettyJson<'a, T> {
+    /// Set the indentation level for the emitted JSON
+    pub fn indent(mut self, indent: uint) -> AsPrettyJson<'a, T> {
+        self.indent = Some(indent);
+        self
+    }
+}
+
+impl<'a, T> fmt::Show for AsPrettyJson<'a, T>
+    where T: for<'b> Encodable<PrettyEncoder<'b>, fmt::Error>
+{
+    /// Encodes a json value into a string
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut shim = FormatShim { inner: f };
+        let mut encoder = PrettyEncoder::new(&mut shim);
+        match self.indent {
+            Some(n) => encoder.set_indent(n),
+            None => {}
+        }
+        self.inner.encode(&mut encoder)
     }
 }
 
@@ -2450,9 +2500,9 @@ mod tests {
     use super::DecoderError::*;
     use super::JsonEvent::*;
     use super::StackElement::*;
-    use super::{PrettyEncoder, Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser,
-                StackElement, Stack, Encoder, Decoder};
-    use std::{i64, u64, f32, f64, io};
+    use super::{Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser,
+                StackElement, Stack, Decoder};
+    use std::{i64, u64, f32, f64};
     use std::collections::BTreeMap;
     use std::num::Float;
     use std::string;
@@ -2523,74 +2573,74 @@ mod tests {
     #[test]
     fn test_write_null() {
         assert_eq!(Null.to_string(), "null");
-        assert_eq!(Null.to_pretty_str(), "null");
+        assert_eq!(Null.pretty().to_string(), "null");
     }
 
     #[test]
     fn test_write_i64() {
         assert_eq!(U64(0).to_string(), "0");
-        assert_eq!(U64(0).to_pretty_str(), "0");
+        assert_eq!(U64(0).pretty().to_string(), "0");
 
         assert_eq!(U64(1234).to_string(), "1234");
-        assert_eq!(U64(1234).to_pretty_str(), "1234");
+        assert_eq!(U64(1234).pretty().to_string(), "1234");
 
         assert_eq!(I64(-5678).to_string(), "-5678");
-        assert_eq!(I64(-5678).to_pretty_str(), "-5678");
+        assert_eq!(I64(-5678).pretty().to_string(), "-5678");
 
         assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000");
-        assert_eq!(U64(7650007200025252000).to_pretty_str(), "7650007200025252000");
+        assert_eq!(U64(7650007200025252000).pretty().to_string(), "7650007200025252000");
     }
 
     #[test]
     fn test_write_f64() {
         assert_eq!(F64(3.0).to_string(), "3.0");
-        assert_eq!(F64(3.0).to_pretty_str(), "3.0");
+        assert_eq!(F64(3.0).pretty().to_string(), "3.0");
 
         assert_eq!(F64(3.1).to_string(), "3.1");
-        assert_eq!(F64(3.1).to_pretty_str(), "3.1");
+        assert_eq!(F64(3.1).pretty().to_string(), "3.1");
 
         assert_eq!(F64(-1.5).to_string(), "-1.5");
-        assert_eq!(F64(-1.5).to_pretty_str(), "-1.5");
+        assert_eq!(F64(-1.5).pretty().to_string(), "-1.5");
 
         assert_eq!(F64(0.5).to_string(), "0.5");
-        assert_eq!(F64(0.5).to_pretty_str(), "0.5");
+        assert_eq!(F64(0.5).pretty().to_string(), "0.5");
 
         assert_eq!(F64(f64::NAN).to_string(), "null");
-        assert_eq!(F64(f64::NAN).to_pretty_str(), "null");
+        assert_eq!(F64(f64::NAN).pretty().to_string(), "null");
 
         assert_eq!(F64(f64::INFINITY).to_string(), "null");
-        assert_eq!(F64(f64::INFINITY).to_pretty_str(), "null");
+        assert_eq!(F64(f64::INFINITY).pretty().to_string(), "null");
 
         assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null");
-        assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str(), "null");
+        assert_eq!(F64(f64::NEG_INFINITY).pretty().to_string(), "null");
     }
 
     #[test]
     fn test_write_str() {
         assert_eq!(String("".to_string()).to_string(), "\"\"");
-        assert_eq!(String("".to_string()).to_pretty_str(), "\"\"");
+        assert_eq!(String("".to_string()).pretty().to_string(), "\"\"");
 
         assert_eq!(String("homura".to_string()).to_string(), "\"homura\"");
-        assert_eq!(String("madoka".to_string()).to_pretty_str(), "\"madoka\"");
+        assert_eq!(String("madoka".to_string()).pretty().to_string(), "\"madoka\"");
     }
 
     #[test]
     fn test_write_bool() {
         assert_eq!(Boolean(true).to_string(), "true");
-        assert_eq!(Boolean(true).to_pretty_str(), "true");
+        assert_eq!(Boolean(true).pretty().to_string(), "true");
 
         assert_eq!(Boolean(false).to_string(), "false");
-        assert_eq!(Boolean(false).to_pretty_str(), "false");
+        assert_eq!(Boolean(false).pretty().to_string(), "false");
     }
 
     #[test]
     fn test_write_array() {
         assert_eq!(Array(vec![]).to_string(), "[]");
-        assert_eq!(Array(vec![]).to_pretty_str(), "[]");
+        assert_eq!(Array(vec![]).pretty().to_string(), "[]");
 
         assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]");
         assert_eq!(
-            Array(vec![Boolean(true)]).to_pretty_str(),
+            Array(vec![Boolean(true)]).pretty().to_string(),
             "\
             [\n  \
                 true\n\
@@ -2605,7 +2655,7 @@ mod tests {
         assert_eq!(long_test_array.to_string(),
             "[false,null,[\"foo\\nbar\",3.5]]");
         assert_eq!(
-            long_test_array.to_pretty_str(),
+            long_test_array.pretty().to_string(),
             "\
             [\n  \
                 false,\n  \
@@ -2621,7 +2671,7 @@ mod tests {
     #[test]
     fn test_write_object() {
         assert_eq!(mk_object(&[]).to_string(), "{}");
-        assert_eq!(mk_object(&[]).to_pretty_str(), "{}");
+        assert_eq!(mk_object(&[]).pretty().to_string(), "{}");
 
         assert_eq!(
             mk_object(&[
@@ -2630,7 +2680,7 @@ mod tests {
             "{\"a\":true}"
         );
         assert_eq!(
-            mk_object(&[("a".to_string(), Boolean(true))]).to_pretty_str(),
+            mk_object(&[("a".to_string(), Boolean(true))]).pretty().to_string(),
             "\
             {\n  \
                 \"a\": true\n\
@@ -2654,7 +2704,7 @@ mod tests {
             }"
         );
         assert_eq!(
-            complex_obj.to_pretty_str(),
+            complex_obj.pretty().to_string(),
             "\
             {\n  \
                 \"b\": [\n    \
@@ -2678,48 +2728,29 @@ mod tests {
 
         // We can't compare the strings directly because the object fields be
         // printed in a different order.
-        assert_eq!(a.clone(), from_str(a.to_string().as_slice()).unwrap());
-        assert_eq!(a.clone(),
-                   from_str(a.to_pretty_str().as_slice()).unwrap());
-    }
-
-    fn with_str_writer<F>(f: F) -> string::String where F: FnOnce(&mut io::Writer){
-        let mut m = Vec::new();
-        f(&mut m as &mut io::Writer);
-        string::String::from_utf8(m).unwrap()
+        assert_eq!(a.clone(), a.to_string().parse().unwrap());
+        assert_eq!(a.clone(), a.pretty().to_string().parse().unwrap());
     }
 
     #[test]
     fn test_write_enum() {
         let animal = Dog;
         assert_eq!(
-            with_str_writer(|writer| {
-                let mut encoder = Encoder::new(writer);
-                animal.encode(&mut encoder).unwrap();
-            }),
+            format!("{}", super::as_json(&animal)),
             "\"Dog\""
         );
         assert_eq!(
-            with_str_writer(|writer| {
-                let mut encoder = PrettyEncoder::new(writer);
-                animal.encode(&mut encoder).unwrap();
-            }),
+            format!("{}", super::as_pretty_json(&animal)),
             "\"Dog\""
         );
 
         let animal = Frog("Henry".to_string(), 349);
         assert_eq!(
-            with_str_writer(|writer| {
-                let mut encoder = Encoder::new(writer);
-                animal.encode(&mut encoder).unwrap();
-            }),
+            format!("{}", super::as_json(&animal)),
             "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
         );
         assert_eq!(
-            with_str_writer(|writer| {
-                let mut encoder = PrettyEncoder::new(writer);
-                animal.encode(&mut encoder).unwrap();
-            }),
+            format!("{}", super::as_pretty_json(&animal)),
             "{\n  \
                \"variant\": \"Frog\",\n  \
                \"fields\": [\n    \
@@ -2732,16 +2763,10 @@ mod tests {
 
     macro_rules! check_encoder_for_simple {
         ($value:expr, $expected:expr) => ({
-            let s = with_str_writer(|writer| {
-                let mut encoder = Encoder::new(writer);
-                $value.encode(&mut encoder).unwrap();
-            });
+            let s = format!("{}", super::as_json(&$value));
             assert_eq!(s, $expected);
 
-            let s = with_str_writer(|writer| {
-                let mut encoder = PrettyEncoder::new(writer);
-                $value.encode(&mut encoder).unwrap();
-            });
+            let s = format!("{}", super::as_pretty_json(&$value));
             assert_eq!(s, $expected);
         })
     }
@@ -3320,10 +3345,7 @@ mod tests {
         let mut hm: HashMap<uint, bool> = HashMap::new();
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
-        {
-            let mut encoder = Encoder::new(&mut mem_buf as &mut io::Writer);
-            hm.encode(&mut encoder).unwrap();
-        }
+        write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
         let json_str = from_utf8(mem_buf[]).unwrap();
         match from_str(json_str) {
             Err(_) => panic!("Unable to parse json_str: {}", json_str),
@@ -3339,10 +3361,7 @@ mod tests {
         let mut hm: HashMap<uint, bool> = HashMap::new();
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
-        {
-            let mut encoder = PrettyEncoder::new(&mut mem_buf as &mut io::Writer);
-            hm.encode(&mut encoder).unwrap()
-        }
+        write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
         let json_str = from_utf8(mem_buf[]).unwrap();
         match from_str(json_str) {
             Err(_) => panic!("Unable to parse json_str: {}", json_str),
@@ -3373,18 +3392,15 @@ mod tests {
 
         // Helper function for counting indents
         fn indents(source: &str) -> uint {
-            let trimmed = source.trim_left_chars(' ');
+            let trimmed = source.trim_left_matches(' ');
             source.len() - trimmed.len()
         }
 
         // Test up to 4 spaces of indents (more?)
         for i in range(0, 4u) {
             let mut writer = Vec::new();
-            {
-                let ref mut encoder = PrettyEncoder::new(&mut writer);
-                encoder.set_indent(i);
-                json.encode(encoder).unwrap();
-            }
+            write!(&mut writer, "{}",
+                   super::as_pretty_json(&json).indent(i)).unwrap();
 
             let printed = from_utf8(writer[]).unwrap();
 
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 2c2b7313a7b..857a7072009 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -315,8 +315,8 @@ static ASCII_UPPERCASE_MAP: [u8; 256] = [
 
 #[cfg(test)]
 mod tests {
+    use prelude::v1::*;
     use super::*;
-    use prelude::*;
     use char::from_u32;
 
     #[test]
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index aeb4df402a2..c07531d3f32 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -209,7 +209,7 @@ macro_rules! bitflags {
             }
         }
 
-        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::BitOr<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the union of the two sets of flags.
             #[inline]
             fn bitor(self, other: $BitFlags) -> $BitFlags {
@@ -217,7 +217,7 @@ macro_rules! bitflags {
             }
         }
 
-        impl BitXor<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::BitXor<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the left flags, but with all the right flags toggled.
             #[inline]
             fn bitxor(self, other: $BitFlags) -> $BitFlags {
@@ -225,7 +225,7 @@ macro_rules! bitflags {
             }
         }
 
-        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::BitAnd<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the intersection between the two sets of flags.
             #[inline]
             fn bitand(self, other: $BitFlags) -> $BitFlags {
@@ -233,7 +233,7 @@ macro_rules! bitflags {
             }
         }
 
-        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::Sub<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the set difference of the two sets of flags.
             #[inline]
             fn sub(self, other: $BitFlags) -> $BitFlags {
@@ -241,7 +241,7 @@ macro_rules! bitflags {
             }
         }
 
-        impl Not<$BitFlags> for $BitFlags {
+        impl ::std::ops::Not<$BitFlags> for $BitFlags {
             /// Returns the complement of this set of flags.
             #[inline]
             fn not(self) -> $BitFlags {
@@ -266,7 +266,6 @@ macro_rules! bitflags {
 mod tests {
     use hash;
     use option::Option::{Some, None};
-    use ops::{BitOr, BitAnd, BitXor, Sub, Not};
 
     bitflags! {
         #[doc = "> The first principle is that you must not fool yourself — and"]
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
index 46498610e56..b1433ad7fdc 100644
--- a/src/libstd/c_str.rs
+++ b/src/libstd/c_str.rs
@@ -45,6 +45,8 @@
 //! ```rust
 //! extern crate libc;
 //!
+//! use std::c_str::ToCStr;
+//!
 //! extern {
 //!     fn puts(s: *const libc::c_char);
 //! }
@@ -70,6 +72,7 @@
 use core::prelude::*;
 use libc;
 
+use cmp::Ordering;
 use fmt;
 use hash;
 use mem;
@@ -155,6 +158,8 @@ impl CString {
     /// one).
     ///
     /// ```rust
+    /// use std::c_str::ToCStr;
+    ///
     /// let foo = "some string";
     ///
     /// // right
@@ -170,6 +175,8 @@ impl CString {
     /// ```rust
     /// extern crate libc;
     ///
+    /// use std::c_str::ToCStr;
+    ///
     /// fn main() {
     ///     let c_str = "foo bar".to_c_str();
     ///     unsafe {
@@ -189,6 +196,8 @@ impl CString {
     /// one).
     ///
     /// ```rust
+    /// use std::c_str::ToCStr;
+    ///
     /// let foo = "some string";
     ///
     /// // right
@@ -309,6 +318,8 @@ pub trait ToCStr for Sized? {
     /// ```rust
     /// extern crate libc;
     ///
+    /// use std::c_str::ToCStr;
+    ///
     /// fn main() {
     ///     let s = "PATH".with_c_str(|path| unsafe {
     ///         libc::getenv(path)
@@ -538,9 +549,8 @@ pub unsafe fn from_c_multistring<F>(buf: *const libc::c_char,
 
 #[cfg(test)]
 mod tests {
+    use prelude::v1::*;
     use super::*;
-    use prelude::{spawn, Some, None, Option, FnOnce, ToString, CloneSliceExt};
-    use prelude::{Clone, PtrExt, Iterator, SliceExt, StrExt};
     use ptr;
     use thread::Thread;
     use libc;
@@ -613,7 +623,7 @@ mod tests {
     #[test]
     fn test_unwrap() {
         let c_str = "hello".to_c_str();
-        unsafe { libc::free(c_str.unwrap() as *mut libc::c_void) }
+        unsafe { libc::free(c_str.into_inner() as *mut libc::c_void) }
     }
 
     #[test]
@@ -732,9 +742,10 @@ mod tests {
 mod bench {
     extern crate test;
 
+    use prelude::v1::*;
     use self::test::Bencher;
     use libc;
-    use prelude::*;
+    use c_str::ToCStr;
 
     #[inline]
     fn check(s: &str, c_str: *const libc::c_char) {
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
index 0aa51ee66ed..40942f1b987 100644
--- a/src/libstd/c_vec.rs
+++ b/src/libstd/c_vec.rs
@@ -172,7 +172,7 @@ impl<T> AsSlice<T> for CVec<T> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
 
     use super::CVec;
     use libc;
@@ -228,7 +228,7 @@ mod tests {
             let cv = CVec::new_with_dtor(1 as *mut int,
                                          0,
                                          move|:| panic!("Don't run this destructor!"));
-            let p = cv.unwrap();
+            let p = cv.into_inner();
             assert_eq!(p, 1 as *mut int);
         }
     }
diff --git a/src/libstd/collections/hash/bench.rs b/src/libstd/collections/hash/bench.rs
index 87aebb24f98..28689767cb0 100644
--- a/src/libstd/collections/hash/bench.rs
+++ b/src/libstd/collections/hash/bench.rs
@@ -11,7 +11,7 @@
 #![cfg(test)]
 
 extern crate test;
-use prelude::*;
+use prelude::v1::*;
 
 use self::test::Bencher;
 use iter::{range_inclusive};
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index f6063df5434..d4fc4150fae 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -87,7 +87,7 @@ impl DefaultResizePolicy {
 
 #[test]
 fn test_resize_policy() {
-    use prelude::*;
+    use prelude::v1::*;
     let rp = DefaultResizePolicy;
     for n in range(0u, 1000) {
         assert!(rp.min_capacity(rp.usable_capacity(n)) <= n);
@@ -311,7 +311,7 @@ fn search_hashed<K, V, M, F>(table: M,
                              hash: SafeHash,
                              mut is_match: F)
                              -> SearchResult<K, V, M> where
-    M: Deref<RawTable<K, V>>,
+    M: Deref<Target=RawTable<K, V>>,
     F: FnMut(&K) -> bool,
 {
     let size = table.size();
@@ -1530,8 +1530,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extend<(K, V)> for HashMap<K
 
 #[cfg(test)]
 mod test_map {
-    use prelude::*;
+    use prelude::v1::*;
 
+    use cmp::Equiv;
     use super::HashMap;
     use super::Entry::{Occupied, Vacant};
     use hash;
@@ -1541,6 +1542,7 @@ mod test_map {
 
     struct KindaIntLike(int);
 
+    #[allow(deprecated)]
     impl Equiv<int> for KindaIntLike {
         fn equiv(&self, other: &int) -> bool {
             let KindaIntLike(this) = *self;
@@ -1868,7 +1870,7 @@ mod test_map {
     }
 
     #[test]
-    #[allow(experimental)]
+    #[allow(deprecated)]
     fn test_pop_equiv() {
         let mut m = HashMap::new();
         m.insert(1i, 2i);
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 74fb63a7a9e..6132d288da2 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -866,7 +866,7 @@ impl<'a, T, S, H> Iterator<&'a T> for Union<'a, T, H>
 
 #[cfg(test)]
 mod test_set {
-    use prelude::*;
+    use prelude::v1::*;
 
     use super::HashSet;
 
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 6938ab9b0b6..a687ba3da8d 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -210,7 +210,7 @@ impl<K, V, M> Bucket<K, V, M> {
     }
 }
 
-impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> {
+impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
     pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
         Bucket::at_index(table, hash.inspect() as uint)
     }
@@ -279,7 +279,7 @@ impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> {
     }
 }
 
-impl<K, V, M: Deref<RawTable<K, V>>> EmptyBucket<K, V, M> {
+impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> {
     #[inline]
     pub fn next(self) -> Bucket<K, V, M> {
         let mut bucket = self.into_bucket();
@@ -315,7 +315,7 @@ impl<K, V, M: Deref<RawTable<K, V>>> EmptyBucket<K, V, M> {
     }
 }
 
-impl<K, V, M: DerefMut<RawTable<K, V>>> EmptyBucket<K, V, M> {
+impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> EmptyBucket<K, V, M> {
     /// Puts given key and value pair, along with the key's hash,
     /// into this bucket in the hashtable. Note how `self` is 'moved' into
     /// this function, because this slot will no longer be empty when
@@ -337,7 +337,7 @@ impl<K, V, M: DerefMut<RawTable<K, V>>> EmptyBucket<K, V, M> {
     }
 }
 
-impl<K, V, M: Deref<RawTable<K, V>>> FullBucket<K, V, M> {
+impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
     #[inline]
     pub fn next(self) -> Bucket<K, V, M> {
         let mut bucket = self.into_bucket();
@@ -384,7 +384,7 @@ impl<K, V, M: Deref<RawTable<K, V>>> FullBucket<K, V, M> {
     }
 }
 
-impl<K, V, M: DerefMut<RawTable<K, V>>> FullBucket<K, V, M> {
+impl<K, V, M: Deref<Target=RawTable<K, V>> + DerefMut> FullBucket<K, V, M> {
     /// Removes this bucket's key and value from the hashtable.
     ///
     /// This works similarly to `put`, building an `EmptyBucket` out of the
@@ -428,7 +428,7 @@ impl<K, V, M: DerefMut<RawTable<K, V>>> FullBucket<K, V, M> {
     }
 }
 
-impl<'t, K, V, M: Deref<RawTable<K, V>> + 't> FullBucket<K, V, M> {
+impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + 't> FullBucket<K, V, M> {
     /// Exchange a bucket state for immutable references into the table.
     /// Because the underlying reference to the table is also consumed,
     /// no further changes to the structure of the table are possible;
@@ -442,7 +442,7 @@ impl<'t, K, V, M: Deref<RawTable<K, V>> + 't> FullBucket<K, V, M> {
     }
 }
 
-impl<'t, K, V, M: DerefMut<RawTable<K, V>> + 't> FullBucket<K, V, M> {
+impl<'t, K, V, M: Deref<Target=RawTable<K, V>> + DerefMut + 't> FullBucket<K, V, M> {
     /// This works similarly to `into_refs`, exchanging a bucket state
     /// for mutable references into the table.
     pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
@@ -463,7 +463,7 @@ impl<K, V, M> BucketState<K, V, M> {
     }
 }
 
-impl<K, V, M: Deref<RawTable<K, V>>> GapThenFull<K, V, M> {
+impl<K, V, M: Deref<Target=RawTable<K, V>>> GapThenFull<K, V, M> {
     #[inline]
     pub fn full(&self) -> &FullBucket<K, V, M> {
         &self.full
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 368abe7cb12..ecfe2d15ae1 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -15,7 +15,9 @@
 #![experimental]
 #![allow(missing_docs)]
 
-use prelude::*;
+use prelude::v1::*;
+
+use c_str::ToCStr;
 use mem;
 use os;
 use str;
@@ -146,7 +148,7 @@ impl DynamicLibrary {
 #[cfg(all(test, not(target_os = "ios")))]
 mod test {
     use super::*;
-    use prelude::*;
+    use prelude::v1::*;
     use libc;
     use mem;
 
@@ -202,8 +204,8 @@ mod test {
 pub mod dl {
     use self::Rtld::*;
 
-    use prelude::*;
-    use c_str::CString;
+    use prelude::v1::*;
+    use c_str::{CString, ToCStr};
     use libc;
     use ptr;
 
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 9a46a500a4b..32e1922ae74 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -78,7 +78,7 @@
 //! }
 //! ```
 
-use prelude::*;
+use prelude::v1::*;
 
 use str::Utf8Error;
 use string::{FromUtf8Error, FromUtf16Error};
diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs
index 7010eae6dba..d3bcdbf1a53 100644
--- a/src/libstd/failure.rs
+++ b/src/libstd/failure.rs
@@ -10,11 +10,10 @@
 
 #![experimental]
 
-use prelude::*;
+use prelude::v1::*;
 
 use any::{Any, AnyRefExt};
 use cell::RefCell;
-use fmt;
 use io::IoResult;
 use rt::{backtrace, unwind};
 use rt::util::{Stderr, Stdio};
@@ -29,10 +28,7 @@ thread_local! {
 
 impl Writer for Stdio {
     fn write(&mut self, bytes: &[u8]) -> IoResult<()> {
-        fn fmt_write<F: fmt::FormatWriter>(f: &mut F, bytes: &[u8]) {
-            let _ = f.write(bytes);
-        }
-        fmt_write(self, bytes);
+        let _ = self.write_bytes(bytes);
         Ok(())
     }
 }
diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs
index 957dd54a037..32f5f2d4536 100644
--- a/src/libstd/fmt.rs
+++ b/src/libstd/fmt.rs
@@ -201,7 +201,7 @@
 //!         // for details, and the function `pad` can be used to pad strings.
 //!         let decimals = f.precision().unwrap_or(3);
 //!         let string = f64::to_str_exact(magnitude, decimals);
-//!         f.pad_integral(true, "", string.as_bytes())
+//!         f.pad_integral(true, "", string.as_slice())
 //!     }
 //! }
 //!
@@ -390,13 +390,9 @@
 
 #![experimental]
 
-use io::Writer;
-use io;
-use result::Result::{Ok, Err};
 use string;
-use vec::Vec;
 
-pub use core::fmt::{Formatter, Result, FormatWriter, rt};
+pub use core::fmt::{Formatter, Result, Writer, rt};
 pub use core::fmt::{Show, Octal, Binary};
 pub use core::fmt::{LowerHex, UpperHex, Pointer};
 pub use core::fmt::{LowerExp, UpperExp};
@@ -424,16 +420,7 @@ pub use core::fmt::{argument, argumentuint};
 #[experimental = "this is an implementation detail of format! and should not \
                   be called directly"]
 pub fn format(args: Arguments) -> string::String {
-    let mut output = Vec::new();
-    let _ = write!(&mut output as &mut Writer, "{}", args);
-    string::String::from_utf8(output).unwrap()
-}
-
-impl<'a> Writer for Formatter<'a> {
-    fn write(&mut self, b: &[u8]) -> io::IoResult<()> {
-        match (*self).write(b) {
-            Ok(()) => Ok(()),
-            Err(Error) => Err(io::standard_error(io::OtherIoError))
-        }
-    }
+    let mut output = string::String::new();
+    let _ = write!(&mut output, "{}", args);
+    output
 }
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index c5405601048..852cab500f6 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -22,7 +22,6 @@ use result::Result::{Ok, Err};
 use slice::{SliceExt};
 use slice;
 use vec::Vec;
-use kinds::{Send,Sync};
 
 /// Wraps a Reader and buffers input from it
 ///
@@ -52,11 +51,6 @@ pub struct BufferedReader<R> {
     cap: uint,
 }
 
-
-unsafe impl<R: Send> Send for BufferedReader<R> {}
-unsafe impl<R: Send+Sync> Sync for BufferedReader<R> {}
-
-
 impl<R: Reader> BufferedReader<R> {
     /// Creates a new `BufferedReader` with the specified buffer capacity
     pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {
@@ -410,7 +404,7 @@ impl<S: Stream> Writer for BufferedStream<S> {
 mod test {
     extern crate test;
     use io;
-    use prelude::*;
+    use prelude::v1::*;
     use super::*;
     use super::super::{IoResult, EndOfFile};
     use super::super::mem::MemReader;
@@ -534,7 +528,7 @@ mod test {
         w.write(&[0, 1]).unwrap();
         let a: &[_] = &[];
         assert_eq!(a, w.get_ref()[]);
-        let w = w.unwrap();
+        let w = w.into_inner();
         let a: &[_] = &[0, 1];
         assert_eq!(a, w[]);
     }
diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs
index 077f75e2edd..f47f6237b72 100644
--- a/src/libstd/io/comm_adapters.rs
+++ b/src/libstd/io/comm_adapters.rs
@@ -10,11 +10,11 @@
 
 use clone::Clone;
 use cmp;
-use comm::{Sender, Receiver};
+use sync::mpsc::{Sender, Receiver};
 use io;
 use option::Option::{None, Some};
 use result::Result::{Ok, Err};
-use slice::{bytes, CloneSliceExt, SliceExt};
+use slice::{bytes, SliceExt};
 use super::{Buffer, Reader, Writer, IoResult};
 use vec::Vec;
 
@@ -23,6 +23,7 @@ use vec::Vec;
 /// # Example
 ///
 /// ```
+/// use std::sync::mpsc::channel;
 /// use std::io::ChanReader;
 ///
 /// let (tx, rx) = channel();
@@ -58,11 +59,11 @@ impl Buffer for ChanReader {
     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
         if self.pos >= self.buf.len() {
             self.pos = 0;
-            match self.rx.recv_opt() {
+            match self.rx.recv() {
                 Ok(bytes) => {
                     self.buf = bytes;
                 },
-                Err(()) => {
+                Err(..) => {
                     self.closed = true;
                     self.buf = Vec::new();
                 }
@@ -114,6 +115,7 @@ impl Reader for ChanReader {
 ///
 /// ```
 /// # #![allow(unused_must_use)]
+/// use std::sync::mpsc::channel;
 /// use std::io::ChanWriter;
 ///
 /// let (tx, rx) = channel();
@@ -141,7 +143,7 @@ impl Clone for ChanWriter {
 
 impl Writer for ChanWriter {
     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.tx.send_opt(buf.to_vec()).map_err(|_| {
+        self.tx.send(buf.to_vec()).map_err(|_| {
             io::IoError {
                 kind: io::BrokenPipe,
                 desc: "Pipe closed",
@@ -154,7 +156,9 @@ impl Writer for ChanWriter {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
+
+    use sync::mpsc::channel;
     use super::*;
     use io;
     use thread::Thread;
@@ -163,11 +167,11 @@ mod test {
     fn test_rx_reader() {
         let (tx, rx) = channel();
         Thread::spawn(move|| {
-          tx.send(vec![1u8, 2u8]);
-          tx.send(vec![]);
-          tx.send(vec![3u8, 4u8]);
-          tx.send(vec![5u8, 6u8]);
-          tx.send(vec![7u8, 8u8]);
+          tx.send(vec![1u8, 2u8]).unwrap();
+          tx.send(vec![]).unwrap();
+          tx.send(vec![3u8, 4u8]).unwrap();
+          tx.send(vec![5u8, 6u8]).unwrap();
+          tx.send(vec![7u8, 8u8]).unwrap();
         }).detach();
 
         let mut reader = ChanReader::new(rx);
@@ -205,12 +209,12 @@ mod test {
     fn test_rx_buffer() {
         let (tx, rx) = channel();
         Thread::spawn(move|| {
-          tx.send(b"he".to_vec());
-          tx.send(b"llo wo".to_vec());
-          tx.send(b"".to_vec());
-          tx.send(b"rld\nhow ".to_vec());
-          tx.send(b"are you?".to_vec());
-          tx.send(b"".to_vec());
+          tx.send(b"he".to_vec()).unwrap();
+          tx.send(b"llo wo".to_vec()).unwrap();
+          tx.send(b"".to_vec()).unwrap();
+          tx.send(b"rld\nhow ".to_vec()).unwrap();
+          tx.send(b"are you?".to_vec()).unwrap();
+          tx.send(b"".to_vec()).unwrap();
         }).detach();
 
         let mut reader = ChanReader::new(rx);
@@ -230,7 +234,7 @@ mod test {
         writer.write_be_u32(42).unwrap();
 
         let wanted = vec![0u8, 0u8, 0u8, 42u8];
-        let got = match Thread::spawn(move|| { rx.recv() }).join() {
+        let got = match Thread::spawn(move|| { rx.recv().unwrap() }).join() {
             Ok(got) => got,
             Err(_) => panic!(),
         };
diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs
index 51e09e547e3..94dba1f7cc7 100644
--- a/src/libstd/io/extensions.rs
+++ b/src/libstd/io/extensions.rs
@@ -175,7 +175,7 @@ pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use io;
     use io::{MemReader, BytesReader};
 
@@ -507,7 +507,7 @@ mod test {
 mod bench {
     extern crate test;
 
-    use prelude::*;
+    use prelude::v1::*;
     use self::test::Bencher;
 
     // why is this a macro? wouldn't an inlined function work just as well?
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index 7fa6ebc6e3b..7fa5b3cfac7 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -819,7 +819,7 @@ fn access_string(access: FileAccess) -> &'static str {
 #[allow(unused_variables)]
 #[allow(unused_mut)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use io::{SeekSet, SeekCur, SeekEnd, Read, Open, ReadWrite, FileType};
     use io;
     use str;
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index f8ea373f8f4..ad921e43c0c 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -399,9 +399,10 @@ impl<'a> Buffer for BufReader<'a> {
 #[cfg(test)]
 mod test {
     extern crate "test" as test_crate;
+    use prelude::v1::*;
+
     use super::*;
-    use io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek};
-    use prelude::{Ok, Err, range,  Vec, Buffer,  AsSlice, SliceExt, IteratorExt, CloneSliceExt};
+    use io::{SeekSet, SeekCur, SeekEnd};
     use io;
     use self::test_crate::Bencher;
 
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index e8b852ee492..0a7815aeb53 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -232,8 +232,9 @@ use error::{FromError, Error};
 use fmt;
 use int;
 use iter::{Iterator, IteratorExt};
+use kinds::Sized;
 use mem::transmute;
-use ops::{BitOr, BitXor, BitAnd, Sub, Not, FnOnce};
+use ops::FnOnce;
 use option::Option;
 use option::Option::{Some, None};
 use os;
@@ -1028,16 +1029,30 @@ pub trait Writer {
     ///
     /// This function will return any I/O error reported while formatting.
     fn write_fmt(&mut self, fmt: fmt::Arguments) -> IoResult<()> {
-        // Create a shim which translates a Writer to a FormatWriter and saves
+        // Create a shim which translates a Writer to a fmt::Writer and saves
         // off I/O errors. instead of discarding them
-        struct Adaptor<'a, T:'a> {
+        struct Adaptor<'a, Sized? T:'a> {
             inner: &'a mut T,
             error: IoResult<()>,
         }
 
-        impl<'a, T: Writer> fmt::FormatWriter for Adaptor<'a, T> {
-            fn write(&mut self, bytes: &[u8]) -> fmt::Result {
-                match self.inner.write(bytes) {
+        #[cfg(not(stage0))]
+        impl<'a, Sized? T: Writer> fmt::Writer for Adaptor<'a, T> {
+            fn write_str(&mut self, s: &str) -> fmt::Result {
+                match self.inner.write(s.as_bytes()) {
+                    Ok(()) => Ok(()),
+                    Err(e) => {
+                        self.error = Err(e);
+                        Err(fmt::Error)
+                    }
+                }
+            }
+        }
+
+        #[cfg(stage0)]
+        impl<'a, T: Writer> fmt::Writer for Adaptor<'a, T> {
+            fn write_str(&mut self, s: &str) -> fmt::Result {
+                match self.inner.write(s.as_bytes()) {
                     Ok(()) => Ok(()),
                     Err(e) => {
                         self.error = Err(e);
@@ -1629,16 +1644,24 @@ pub trait Acceptor<T> {
 /// `Some`. The `Some` contains the `IoResult` representing whether the
 /// connection attempt was successful.  A successful connection will be wrapped
 /// in `Ok`. A failed connection is represented as an `Err`.
-pub struct IncomingConnections<'a, A:'a> {
+pub struct IncomingConnections<'a, Sized? A:'a> {
     inc: &'a mut A,
 }
 
+#[cfg(stage0)]
 impl<'a, T, A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
     fn next(&mut self) -> Option<IoResult<T>> {
         Some(self.inc.accept())
     }
 }
 
+#[cfg(not(stage0))]
+impl<'a, T, Sized? A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
+    fn next(&mut self) -> Option<IoResult<T>> {
+        Some(self.inc.accept())
+    }
+}
+
 /// Creates a standard error for a commonly used flavor of error. The `detail`
 /// field of the returned error will always be `None`.
 ///
@@ -1919,7 +1942,7 @@ impl fmt::Show for FilePermission {
 mod tests {
     use self::BadReaderBehavior::*;
     use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer};
-    use prelude::{Ok, Vec, Buffer, CloneSliceExt};
+    use prelude::v1::{Ok, Vec, Buffer, SliceExt};
     use uint;
 
     #[deriving(Clone, PartialEq, Show)]
diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs
index e8fbb121181..d86cb841f96 100644
--- a/src/libstd/io/net/addrinfo.rs
+++ b/src/libstd/io/net/addrinfo.rs
@@ -112,7 +112,7 @@ fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>)
 // permission without help of apk
 #[cfg(all(test, not(target_os = "android")))]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use super::*;
     use io::net::ip::*;
 
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index 49ab9ddb924..2a18b839778 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -25,7 +25,7 @@ use ops::FnOnce;
 use option::Option;
 use option::Option::{None, Some};
 use result::Result::{Ok, Err};
-use slice::{CloneSliceExt, SliceExt};
+use slice::SliceExt;
 use str::{FromStr, StrExt};
 use vec::Vec;
 
@@ -544,7 +544,7 @@ impl<'a> ToSocketAddr for &'a str {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use super::*;
     use str::FromStr;
 
diff --git a/src/libstd/io/net/pipe.rs b/src/libstd/io/net/pipe.rs
index 6ce66c3273b..daefdd28b30 100644
--- a/src/libstd/io/net/pipe.rs
+++ b/src/libstd/io/net/pipe.rs
@@ -20,14 +20,14 @@
 
 #![allow(missing_docs)]
 
-use prelude::*;
+use prelude::v1::*;
 
+use c_str::ToCStr;
 use io::{Listener, Acceptor, IoResult, TimedOut, standard_error};
-use time::Duration;
-
-use sys::pipe::UnixStream as UnixStreamImp;
-use sys::pipe::UnixListener as UnixListenerImp;
 use sys::pipe::UnixAcceptor as UnixAcceptorImp;
+use sys::pipe::UnixListener as UnixListenerImp;
+use sys::pipe::UnixStream as UnixStreamImp;
+use time::Duration;
 
 use sys_common;
 
@@ -264,13 +264,17 @@ impl sys_common::AsInner<UnixAcceptorImp> for UnixAcceptor {
 }
 
 #[cfg(test)]
-#[allow(experimental)]
 mod tests {
-    use super::*;
-    use io::*;
-    use io::test::*;
-    use prelude::{Ok, Err, spawn, range, drop,  Some, None, channel, Send, FnOnce, Clone};
+    use prelude::v1::*;
+
     use io::fs::PathExtensions;
+    use io::{EndOfFile, TimedOut, ShortWrite, IoError, ConnectionReset};
+    use io::{NotConnected, BrokenPipe, FileNotFound, InvalidInput, OtherIoError};
+    use io::{PermissionDenied, Acceptor, Listener};
+    use io::test::*;
+    use super::*;
+    use sync::mpsc::channel;
+    use thread::Thread;
     use time::Duration;
 
     pub fn smalltest<F,G>(server: F, client: G)
@@ -282,7 +286,7 @@ mod tests {
 
         let mut acceptor = UnixListener::bind(&path1).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             match UnixStream::connect(&path2) {
                 Ok(c) => client(c),
                 Err(e) => panic!("failed connect: {}", e),
@@ -377,7 +381,7 @@ mod tests {
             Err(e) => panic!("failed listen: {}", e),
         };
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             for _ in range(0u, times) {
                 let mut stream = UnixStream::connect(&path2);
                 match stream.write(&[100]) {
@@ -411,7 +415,7 @@ mod tests {
         let addr = next_test_unix();
         let mut acceptor = UnixListener::bind(&addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr);
             let mut buf = [0, 0];
             debug!("client reading");
@@ -427,20 +431,20 @@ mod tests {
 
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
-            rx1.recv();
+            rx1.recv().unwrap();
             debug!("writer writing");
             s2.write(&[1]).unwrap();
             debug!("writer done");
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
-        tx1.send(());
+        tx1.send(()).unwrap();
         let mut buf = [0, 0];
         debug!("reader reading");
         assert_eq!(s1.read(&mut buf), Ok(1));
         debug!("reader done");
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[test]
@@ -450,30 +454,30 @@ mod tests {
         let (tx1, rx) = channel();
         let tx2 = tx1.clone();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr);
             s.write(&[1]).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             s.write(&[2]).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
         });
 
         let mut s1 = acceptor.accept().unwrap();
         let s2 = s1.clone();
 
         let (done, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             let mut buf = [0, 0];
             s2.read(&mut buf).unwrap();
-            tx2.send(());
-            done.send(());
+            tx2.send(()).unwrap();
+            done.send(()).unwrap();
         });
         let mut buf = [0, 0];
         s1.read(&mut buf).unwrap();
-        tx1.send(());
+        tx1.send(()).unwrap();
 
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -481,7 +485,7 @@ mod tests {
         let addr = next_test_unix();
         let mut acceptor = UnixListener::bind(&addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr);
             let buf = &mut [0, 1];
             s.read(buf).unwrap();
@@ -492,14 +496,14 @@ mod tests {
         let s2 = s1.clone();
 
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             s2.write(&[1]).unwrap();
-            tx.send(());
+            tx.send(()).unwrap();
         });
         s1.write(&[2]).unwrap();
 
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[cfg(not(windows))]
@@ -539,10 +543,10 @@ mod tests {
         // continue to receive any pending connections.
         let (tx, rx) = channel();
         let addr2 = addr.clone();
-        spawn(move|| {
-            tx.send(UnixStream::connect(&addr2).unwrap());
+        let _t = Thread::spawn(move|| {
+            tx.send(UnixStream::connect(&addr2).unwrap()).unwrap();
         });
-        let l = rx.recv();
+        let l = rx.recv().unwrap();
         for i in range(0u, 1001) {
             match a.accept() {
                 Ok(..) => break,
@@ -557,7 +561,7 @@ mod tests {
         // Unset the timeout and make sure that this always blocks.
         a.set_timeout(None);
         let addr2 = addr.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             drop(UnixStream::connect(&addr2).unwrap());
         });
         a.accept().unwrap();
@@ -595,11 +599,11 @@ mod tests {
         let addr = next_test_unix();
         let a = UnixListener::bind(&addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut b = [0];
         let mut s = UnixStream::connect(&addr).unwrap();
@@ -632,25 +636,25 @@ mod tests {
         let addr = next_test_unix();
         let a = UnixListener::bind(&addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = UnixStream::connect(&addr).unwrap();
         let s2 = s.clone();
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             assert!(s2.read(&mut [0]).is_err());
-            tx.send(());
+            tx.send(()).unwrap();
         });
         // this should wake up the child task
         s.close_read().unwrap();
 
         // this test will never finish if the child doesn't wake up
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -658,12 +662,12 @@ mod tests {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         s.set_timeout(Some(20));
@@ -686,7 +690,7 @@ mod tests {
             assert_eq!(s.write(&[0]).err().unwrap().kind, TimedOut);
         }
 
-        tx.send(());
+        tx.send(()).unwrap();
         s.set_timeout(None);
         assert_eq!(s.read(&mut [0, 0]), Ok(1));
     }
@@ -696,9 +700,9 @@ mod tests {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             let mut amt = 0;
             while amt < 100 * 128 * 1024 {
                 match s.read(&mut [0;128 * 1024]) {
@@ -706,15 +710,15 @@ mod tests {
                     Err(e) => panic!("{}", e),
                 }
             }
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         s.set_read_timeout(Some(20));
         assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
         assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
 
-        tx.send(());
+        tx.send(()).unwrap();
         for _ in range(0u, 100) {
             assert!(s.write(&[0;128 * 1024]).is_ok());
         }
@@ -725,12 +729,12 @@ mod tests {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         s.set_write_timeout(Some(20));
@@ -743,7 +747,7 @@ mod tests {
            if i == 1000 { panic!("should have filled up?!"); }
         }
 
-        tx.send(());
+        tx.send(()).unwrap();
         assert!(s.read(&mut [0]).is_ok());
     }
 
@@ -752,27 +756,27 @@ mod tests {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         let s2 = s.clone();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             assert!(s2.read(&mut [0]).is_ok());
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         s.set_read_timeout(Some(20));
         assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
-        tx.send(());
+        tx.send(()).unwrap();
 
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[cfg(not(windows))]
@@ -784,10 +788,10 @@ mod tests {
         let mut a2 = a.clone();
 
         let addr2 = addr.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = UnixStream::connect(&addr2);
         });
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = UnixStream::connect(&addr);
         });
 
@@ -807,19 +811,25 @@ mod tests {
         let (tx, rx) = channel();
         let tx2 = tx.clone();
 
-        spawn(move|| { let mut a = a; tx.send(a.accept()) });
-        spawn(move|| { let mut a = a2; tx2.send(a.accept()) });
+        let _t = Thread::spawn(move|| {
+            let mut a = a;
+            tx.send(a.accept()).unwrap()
+        });
+        let _t = Thread::spawn(move|| {
+            let mut a = a2;
+            tx2.send(a.accept()).unwrap()
+        });
 
         let addr2 = addr.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = UnixStream::connect(&addr2);
         });
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = UnixStream::connect(&addr);
         });
 
-        assert!(rx.recv().is_ok());
-        assert!(rx.recv().is_ok());
+        assert!(rx.recv().unwrap().is_ok());
+        assert!(rx.recv().unwrap().is_ok());
     }
 
     #[test]
@@ -840,12 +850,12 @@ mod tests {
         let mut a2 = a.clone();
 
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut a = a;
-            tx.send(a.accept());
+            tx.send(a.accept()).unwrap();
         });
         a2.close_accept().unwrap();
 
-        assert_eq!(rx.recv().err().unwrap().kind, EndOfFile);
+        assert_eq!(rx.recv().unwrap().err().unwrap().kind, EndOfFile);
     }
 }
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index 826f492d85d..3e59aaa05ef 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -141,7 +141,7 @@ impl TcpStream {
     /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
     /// let stream2 = stream.clone();
     ///
-    /// Thread::spawn(move|| {
+    /// let _t = Thread::spawn(move|| {
     ///     // close this stream after one second
     ///     timer::sleep(Duration::seconds(1));
     ///     let mut stream = stream2;
@@ -282,10 +282,10 @@ impl sys_common::AsInner<TcpStreamImp> for TcpStream {
 /// use std::io::{Acceptor, Listener};
 /// use std::thread::Thread;
 ///
-/// let listener = TcpListener::bind("127.0.0.1:80");
+/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
 ///
 /// // bind the listener to the specified address
-/// let mut acceptor = listener.listen();
+/// let mut acceptor = listener.listen().unwrap();
 ///
 /// fn handle_client(mut stream: TcpStream) {
 ///     // ...
@@ -423,7 +423,7 @@ impl TcpAcceptor {
     /// let mut a = TcpListener::bind("127.0.0.1:8482").listen().unwrap();
     /// let a2 = a.clone();
     ///
-    /// Thread::spawn(move|| {
+    /// let _t = Thread::spawn(move|| {
     ///     let mut a2 = a2;
     ///     for socket in a2.incoming() {
     ///         match socket {
@@ -482,14 +482,17 @@ impl sys_common::AsInner<TcpAcceptorImp> for TcpAcceptor {
 #[cfg(test)]
 #[allow(experimental)]
 mod test {
+    use prelude::v1::*;
+
+    use sync::mpsc::channel;
+    use thread::Thread;
     use io::net::tcp::*;
     use io::net::ip::*;
-    use io::{EndOfFile, TimedOut, IoError, ShortWrite, OtherIoError, ConnectionAborted};
-    use io::{ConnectionRefused, ConnectionReset, BrokenPipe, NotConnected};
-    use io::{PermissionDenied, Listener, Acceptor};
     use io::test::*;
-    use prelude::{Ok, Err, spawn, range, drop, Some, None, channel, Clone};
-    use prelude::{Reader, Writer, IteratorExt};
+    use io::{EndOfFile, TimedOut, ShortWrite, IoError};
+    use io::{ConnectionRefused, BrokenPipe, ConnectionAborted};
+    use io::{ConnectionReset, NotConnected, PermissionDenied, OtherIoError};
+    use io::{Acceptor, Listener};
 
     // FIXME #11530 this fails on android because tests are run as root
     #[cfg_attr(any(windows, target_os = "android"), ignore)]
@@ -515,7 +518,7 @@ mod test {
         let listener = TcpListener::bind(socket_addr);
         let mut acceptor = listener.listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut stream = TcpStream::connect(("localhost", socket_addr.port));
             stream.write(&[144]).unwrap();
         });
@@ -531,7 +534,7 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut stream = TcpStream::connect(("localhost", addr.port));
             stream.write(&[64]).unwrap();
         });
@@ -547,7 +550,7 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut stream = TcpStream::connect(("127.0.0.1", addr.port));
             stream.write(&[44]).unwrap();
         });
@@ -563,7 +566,7 @@ mod test {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut stream = TcpStream::connect(("::1", addr.port));
             stream.write(&[66]).unwrap();
         });
@@ -579,7 +582,7 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut stream = TcpStream::connect(addr);
             stream.write(&[99]).unwrap();
         });
@@ -595,7 +598,7 @@ mod test {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut stream = TcpStream::connect(addr);
             stream.write(&[99]).unwrap();
         });
@@ -611,7 +614,7 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -627,7 +630,7 @@ mod test {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -643,7 +646,7 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -667,7 +670,7 @@ mod test {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -692,13 +695,13 @@ mod test {
         let mut acceptor = TcpListener::bind(addr).listen();
 
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             drop(TcpStream::connect(addr));
-            tx.send(());
+            tx.send(()).unwrap();
         });
 
         let mut stream = acceptor.accept();
-        rx.recv();
+        rx.recv().unwrap();
         let buf = [0];
         match stream.write(&buf) {
             Ok(..) => {}
@@ -717,13 +720,13 @@ mod test {
         let mut acceptor = TcpListener::bind(addr).listen();
 
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             drop(TcpStream::connect(addr));
-            tx.send(());
+            tx.send(()).unwrap();
         });
 
         let mut stream = acceptor.accept();
-        rx.recv();
+        rx.recv().unwrap();
         let buf = [0];
         match stream.write(&buf) {
             Ok(..) => {}
@@ -742,7 +745,7 @@ mod test {
         let max = 10u;
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             for _ in range(0, max) {
                 let mut stream = TcpStream::connect(addr);
                 stream.write(&[99]).unwrap();
@@ -762,7 +765,7 @@ mod test {
         let max = 10u;
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             for _ in range(0, max) {
                 let mut stream = TcpStream::connect(addr);
                 stream.write(&[99]).unwrap();
@@ -782,11 +785,11 @@ mod test {
         static MAX: int = 10;
         let acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut acceptor = acceptor;
             for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
                 // Start another task to handle the connection
-                spawn(move|| {
+                let _t = Thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -801,7 +804,7 @@ mod test {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -818,11 +821,11 @@ mod test {
         static MAX: int = 10;
         let acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut acceptor = acceptor;
             for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
                 // Start another task to handle the connection
-                spawn(move|| {
+                let _t = Thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -837,7 +840,7 @@ mod test {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -854,11 +857,11 @@ mod test {
         let addr = next_test_ip4();
         let acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut acceptor = acceptor;
             for stream in acceptor.incoming().take(MAX as uint) {
                 // Start another task to handle the connection
-                spawn(move|| {
+                let _t = Thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -873,7 +876,7 @@ mod test {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -890,11 +893,11 @@ mod test {
         let addr = next_test_ip6();
         let acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut acceptor = acceptor;
             for stream in acceptor.incoming().take(MAX as uint) {
                 // Start another task to handle the connection
-                spawn(move|| {
+                let _t = Thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -909,7 +912,7 @@ mod test {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -932,7 +935,7 @@ mod test {
 
     pub fn peer_name(addr: SocketAddr) {
         let acceptor = TcpListener::bind(addr).listen();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut acceptor = acceptor;
             acceptor.accept().unwrap();
         });
@@ -967,22 +970,22 @@ mod test {
     fn partial_read() {
         let addr = next_test_ip4();
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut srv = TcpListener::bind(addr).listen().unwrap();
-            tx.send(());
+            tx.send(()).unwrap();
             let mut cl = srv.accept().unwrap();
             cl.write(&[10]).unwrap();
             let mut b = [0];
             cl.read(&mut b).unwrap();
-            tx.send(());
+            tx.send(()).unwrap();
         });
 
-        rx.recv();
+        rx.recv().unwrap();
         let mut c = TcpStream::connect(addr).unwrap();
         let mut b = [0; 10];
         assert_eq!(c.read(&mut b), Ok(1));
         c.write(&[1]).unwrap();
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -1004,20 +1007,20 @@ mod test {
         let addr = next_test_ip4();
         let (tx, rx) = channel();
 
-        spawn(move|| {
-            rx.recv();
+        let _t = Thread::spawn(move|| {
+            rx.recv().unwrap();
             let _stream = TcpStream::connect(addr).unwrap();
             // Close
-            rx.recv();
+            rx.recv().unwrap();
         });
 
         {
             let mut acceptor = TcpListener::bind(addr).listen();
-            tx.send(());
+            tx.send(()).unwrap();
             {
                 let _stream = acceptor.accept().unwrap();
                 // Close client
-                tx.send(());
+                tx.send(()).unwrap();
             }
             // Close listener
         }
@@ -1029,7 +1032,7 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s = TcpStream::connect(addr);
             let mut buf = [0, 0];
             assert_eq!(s.read(&mut buf), Ok(1));
@@ -1042,16 +1045,16 @@ mod test {
 
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
-            rx1.recv();
+            rx1.recv().unwrap();
             s2.write(&[1]).unwrap();
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
-        tx1.send(());
+        tx1.send(()).unwrap();
         let mut buf = [0, 0];
         assert_eq!(s1.read(&mut buf), Ok(1));
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[test]
@@ -1061,30 +1064,30 @@ mod test {
         let (tx1, rx) = channel();
         let tx2 = tx1.clone();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s = TcpStream::connect(addr);
             s.write(&[1]).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             s.write(&[2]).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
         });
 
         let mut s1 = acceptor.accept().unwrap();
         let s2 = s1.clone();
 
         let (done, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             let mut buf = [0, 0];
             s2.read(&mut buf).unwrap();
-            tx2.send(());
-            done.send(());
+            tx2.send(()).unwrap();
+            done.send(()).unwrap();
         });
         let mut buf = [0, 0];
         s1.read(&mut buf).unwrap();
-        tx1.send(());
+        tx1.send(()).unwrap();
 
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -1092,7 +1095,7 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s = TcpStream::connect(addr);
             let mut buf = [0, 1];
             s.read(&mut buf).unwrap();
@@ -1103,21 +1106,21 @@ mod test {
         let s2 = s1.clone();
 
         let (done, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             s2.write(&[1]).unwrap();
-            done.send(());
+            done.send(()).unwrap();
         });
         s1.write(&[2]).unwrap();
 
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
     fn shutdown_smoke() {
         let addr = next_test_ip4();
         let a = TcpListener::bind(addr).unwrap().listen();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut a = a;
             let mut c = a.accept().unwrap();
             assert_eq!(c.read_to_end(), Ok(vec!()));
@@ -1151,10 +1154,10 @@ mod test {
         //        flakiness.
         if !cfg!(target_os = "freebsd") {
             let (tx, rx) = channel();
-            spawn(move|| {
-                tx.send(TcpStream::connect(addr).unwrap());
+            let _t = Thread::spawn(move|| {
+                tx.send(TcpStream::connect(addr).unwrap()).unwrap();
             });
-            let _l = rx.recv();
+            let _l = rx.recv().unwrap();
             for i in range(0i, 1001) {
                 match a.accept() {
                     Ok(..) => break,
@@ -1168,7 +1171,7 @@ mod test {
 
         // Unset the timeout and make sure that this always blocks.
         a.set_timeout(None);
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             drop(TcpStream::connect(addr).unwrap());
         });
         a.accept().unwrap();
@@ -1179,11 +1182,11 @@ mod test {
         let addr = next_test_ip4();
         let a = TcpListener::bind(addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv().unwrap();
+        }).detach();
 
         let mut b = [0];
         let mut s = TcpStream::connect(addr).unwrap();
@@ -1216,25 +1219,25 @@ mod test {
         let addr = next_test_ip4();
         let a = TcpListener::bind(addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv().unwrap();
+        }).detach();
 
         let mut s = TcpStream::connect(addr).unwrap();
         let s2 = s.clone();
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             assert!(s2.read(&mut [0]).is_err());
-            tx.send(());
+            tx.send(()).unwrap();
         });
         // this should wake up the child task
         s.close_read().unwrap();
 
         // this test will never finish if the child doesn't wake up
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -1242,12 +1245,12 @@ mod test {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         s.set_timeout(Some(20));
@@ -1265,7 +1268,7 @@ mod test {
         }
         assert_eq!(s.write(&[0]).err().unwrap().kind, TimedOut);
 
-        tx.send(());
+        tx.send(()).unwrap();
         s.set_timeout(None);
         assert_eq!(s.read(&mut [0, 0]), Ok(1));
     }
@@ -1275,9 +1278,9 @@ mod test {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             let mut amt = 0;
             while amt < 100 * 128 * 1024 {
                 match s.read(&mut [0;128 * 1024]) {
@@ -1285,15 +1288,15 @@ mod test {
                     Err(e) => panic!("{}", e),
                 }
             }
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         s.set_read_timeout(Some(20));
         assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
         assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
 
-        tx.send(());
+        tx.send(()).unwrap();
         for _ in range(0i, 100) {
             assert!(s.write(&[0;128 * 1024]).is_ok());
         }
@@ -1304,12 +1307,12 @@ mod test {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         s.set_write_timeout(Some(20));
@@ -1323,7 +1326,7 @@ mod test {
         }
         assert_eq!(s.write(&[0]).err().unwrap().kind, TimedOut);
 
-        tx.send(());
+        tx.send(()).unwrap();
         assert!(s.read(&mut [0]).is_ok());
     }
 
@@ -1332,27 +1335,27 @@ mod test {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             assert_eq!(s.write(&[0]), Ok(()));
-            let _ = rx.recv_opt();
-        });
+            let _ = rx.recv();
+        }).detach();
 
         let mut s = a.accept().unwrap();
         let s2 = s.clone();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut s2 = s2;
             assert_eq!(s2.read(&mut [0]), Ok(1));
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         s.set_read_timeout(Some(20));
         assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
-        tx.send(());
+        tx.send(()).unwrap();
 
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[test]
@@ -1365,21 +1368,21 @@ mod test {
         let (tx, rx) = channel();
         let (txdone, rxdone) = channel();
         let txdone2 = txdone.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut tcp = TcpStream::connect(addr).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             tcp.write_u8(0).unwrap();
-            txdone2.send(());
+            txdone2.send(()).unwrap();
         });
 
         // Spawn off a reading clone
         let tcp = accept.accept().unwrap();
         let tcp2 = tcp.clone();
         let txdone3 = txdone.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut tcp2 = tcp2;
             tcp2.read_u8().unwrap();
-            txdone3.send(());
+            txdone3.send(()).unwrap();
         });
 
         // Try to ensure that the reading clone is indeed reading
@@ -1390,9 +1393,9 @@ mod test {
         // clone the handle again while it's reading, then let it finish the
         // read.
         let _ = tcp.clone();
-        tx.send(());
-        rxdone.recv();
-        rxdone.recv();
+        tx.send(()).unwrap();
+        rxdone.recv().unwrap();
+        rxdone.recv().unwrap();
     }
 
     #[test]
@@ -1402,10 +1405,10 @@ mod test {
         let mut a = l.listen().unwrap();
         let mut a2 = a.clone();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
 
@@ -1423,18 +1426,24 @@ mod test {
         let (tx, rx) = channel();
         let tx2 = tx.clone();
 
-        spawn(move|| { let mut a = a; tx.send(a.accept()) });
-        spawn(move|| { let mut a = a2; tx2.send(a.accept()) });
+        let _t = Thread::spawn(move|| {
+            let mut a = a;
+            tx.send(a.accept()).unwrap();
+        });
+        let _t = Thread::spawn(move|| {
+            let mut a = a2;
+            tx2.send(a.accept()).unwrap();
+        });
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
 
-        assert!(rx.recv().is_ok());
-        assert!(rx.recv().is_ok());
+        assert!(rx.recv().unwrap().is_ok());
+        assert!(rx.recv().unwrap().is_ok());
     }
 
     #[test]
@@ -1455,12 +1464,12 @@ mod test {
         let mut a2 = a.clone();
 
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut a = a;
-            tx.send(a.accept());
+            tx.send(a.accept()).unwrap();
         });
         a2.close_accept().unwrap();
 
-        assert_eq!(rx.recv().err().unwrap().kind, EndOfFile);
+        assert_eq!(rx.recv().unwrap().err().unwrap().kind, EndOfFile);
     }
 }
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index 11c2f956c35..6c167359966 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -248,11 +248,14 @@ impl Writer for UdpStream {
 #[cfg(test)]
 #[allow(experimental)]
 mod test {
-    use super::*;
+    use prelude::v1::*;
+
+    use sync::mpsc::channel;
     use io::net::ip::*;
-    use io::{ShortWrite, IoError, TimedOut, PermissionDenied};
     use io::test::*;
-    use prelude::{Ok, Err, spawn, range, drop, Some, None, channel, Clone, Reader, Writer};
+    use io::{IoError, TimedOut, PermissionDenied, ShortWrite};
+    use super::*;
+    use thread::Thread;
 
     // FIXME #11530 this fails on android because tests are run as root
     #[cfg_attr(any(windows, target_os = "android"), ignore)]
@@ -272,20 +275,20 @@ mod test {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             match UdpSocket::bind(client_ip) {
                 Ok(ref mut client) => {
-                    rx1.recv();
+                    rx1.recv().unwrap();
                     client.send_to(&[99], server_ip).unwrap()
                 }
                 Err(..) => panic!()
             }
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         match UdpSocket::bind(server_ip) {
             Ok(ref mut server) => {
-                tx1.send(());
+                tx1.send(()).unwrap();
                 let mut buf = [0];
                 match server.recv_from(&mut buf) {
                     Ok((nread, src)) => {
@@ -298,7 +301,7 @@ mod test {
             }
             Err(..) => panic!()
         }
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[test]
@@ -307,10 +310,10 @@ mod test {
         let client_ip = next_test_ip6();
         let (tx, rx) = channel::<()>();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             match UdpSocket::bind(client_ip) {
                 Ok(ref mut client) => {
-                    rx.recv();
+                    rx.recv().unwrap();
                     client.send_to(&[99], server_ip).unwrap()
                 }
                 Err(..) => panic!()
@@ -319,7 +322,7 @@ mod test {
 
         match UdpSocket::bind(server_ip) {
             Ok(ref mut server) => {
-                tx.send(());
+                tx.send(()).unwrap();
                 let mut buf = [0];
                 match server.recv_from(&mut buf) {
                     Ok((nread, src)) => {
@@ -343,8 +346,8 @@ mod test {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
 
-        spawn(move|| {
-            let send_as = |&: ip, val: &[u8]| {
+        let _t = Thread::spawn(move|| {
+            let send_as = |&:ip, val: &[u8]| {
                 match UdpSocket::bind(ip) {
                     Ok(client) => {
                         let client = box client;
@@ -354,17 +357,17 @@ mod test {
                     Err(..) => panic!()
                 }
             };
-            rx1.recv();
+            rx1.recv().unwrap();
             send_as(dummy_ip, &[98]);
             send_as(client_ip, &[99]);
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         match UdpSocket::bind(server_ip) {
             Ok(server) => {
                 let server = box server;
                 let mut stream = server.connect(client_ip);
-                tx1.send(());
+                tx1.send(()).unwrap();
                 let mut buf = [0];
                 match stream.read(&mut buf) {
                     Ok(nread) => {
@@ -376,7 +379,7 @@ mod test {
             }
             Err(..) => panic!()
         }
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[test]
@@ -387,24 +390,24 @@ mod test {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             match UdpSocket::bind(client_ip) {
                 Ok(client) => {
                     let client = box client;
                     let mut stream = client.connect(server_ip);
-                    rx1.recv();
+                    rx1.recv().unwrap();
                     stream.write(&[99]).unwrap();
                 }
                 Err(..) => panic!()
             }
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         match UdpSocket::bind(server_ip) {
             Ok(server) => {
                 let server = box server;
                 let mut stream = server.connect(client_ip);
-                tx1.send(());
+                tx1.send(()).unwrap();
                 let mut buf = [0];
                 match stream.read(&mut buf) {
                     Ok(nread) => {
@@ -416,7 +419,7 @@ mod test {
             }
             Err(..) => panic!()
         }
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     pub fn socket_name(addr: SocketAddr) {
@@ -449,7 +452,7 @@ mod test {
         let mut sock1 = UdpSocket::bind(addr1).unwrap();
         let sock2 = UdpSocket::bind(addr2).unwrap();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut sock2 = sock2;
             let mut buf = [0, 0];
             assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1)));
@@ -461,16 +464,16 @@ mod test {
 
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut sock3 = sock3;
-            rx1.recv();
+            rx1.recv().unwrap();
             sock3.send_to(&[1], addr2).unwrap();
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
-        tx1.send(());
+        tx1.send(()).unwrap();
         let mut buf = [0, 0];
         assert_eq!(sock1.recv_from(&mut buf), Ok((1, addr2)));
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[test]
@@ -482,29 +485,29 @@ mod test {
         let (tx1, rx) = channel();
         let tx2 = tx1.clone();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut sock2 = sock2;
             sock2.send_to(&[1], addr1).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
             sock2.send_to(&[2], addr1).unwrap();
-            rx.recv();
+            rx.recv().unwrap();
         });
 
         let sock3 = sock1.clone();
 
         let (done, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut sock3 = sock3;
             let mut buf = [0, 0];
             sock3.recv_from(&mut buf).unwrap();
-            tx2.send(());
-            done.send(());
+            tx2.send(()).unwrap();
+            done.send(()).unwrap();
         });
         let mut buf = [0, 0];
         sock1.recv_from(&mut buf).unwrap();
-        tx1.send(());
+        tx1.send(()).unwrap();
 
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -517,38 +520,38 @@ mod test {
         let (tx, rx) = channel();
         let (serv_tx, serv_rx) = channel();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut sock2 = sock2;
             let mut buf = [0, 1];
 
-            rx.recv();
+            rx.recv().unwrap();
             match sock2.recv_from(&mut buf) {
                 Ok(..) => {}
                 Err(e) => panic!("failed receive: {}", e),
             }
-            serv_tx.send(());
+            serv_tx.send(()).unwrap();
         });
 
         let sock3 = sock1.clone();
 
         let (done, rx) = channel();
         let tx2 = tx.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut sock3 = sock3;
             match sock3.send_to(&[1], addr2) {
-                Ok(..) => { let _ = tx2.send_opt(()); }
+                Ok(..) => { let _ = tx2.send(()); }
                 Err(..) => {}
             }
-            done.send(());
+            done.send(()).unwrap();
         });
         match sock1.send_to(&[2], addr2) {
-            Ok(..) => { let _ = tx.send_opt(()); }
+            Ok(..) => { let _ = tx.send(()); }
             Err(..) => {}
         }
         drop(tx);
 
-        rx.recv();
-        serv_rx.recv();
+        rx.recv().unwrap();
+        serv_rx.recv().unwrap();
     }
 
     #[cfg(not(windows))] // FIXME #17553
@@ -561,14 +564,14 @@ mod test {
 
         let (tx, rx) = channel();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut a = a2;
             assert_eq!(a.recv_from(&mut [0]), Ok((1, addr1)));
             assert_eq!(a.send_to(&[0], addr1), Ok(()));
-            rx.recv();
+            rx.recv().unwrap();
             assert_eq!(a.send_to(&[0], addr1), Ok(()));
 
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         // Make sure that reads time out, but writes can continue
@@ -583,11 +586,11 @@ mod test {
 
         // Clearing the timeout should allow for receiving
         a.set_timeout(None);
-        tx.send(());
+        tx.send(()).unwrap();
         assert_eq!(a2.recv_from(&mut [0]), Ok((1, addr2)));
 
         // Make sure the child didn't die
-        rx2.recv();
+        rx2.recv().unwrap();
     }
 
     #[test]
diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs
index 93465d5510b..09dcafb0218 100644
--- a/src/libstd/io/pipe.rs
+++ b/src/libstd/io/pipe.rs
@@ -15,7 +15,7 @@
 
 #![allow(missing_docs)]
 
-use prelude::*;
+use prelude::v1::*;
 
 use io::IoResult;
 use libc;
@@ -112,7 +112,10 @@ impl Writer for PipeStream {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
+
+    use sync::mpsc::channel;
+    use thread::Thread;
 
     #[test]
     fn partial_read() {
@@ -123,14 +126,14 @@ mod test {
         let out = PipeStream::open(writer);
         let mut input = PipeStream::open(reader);
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut out = out;
             out.write(&[10]).unwrap();
-            rx.recv(); // don't close the pipe until the other read has finished
+            rx.recv().unwrap(); // don't close the pipe until the other read has finished
         });
 
         let mut buf = [0; 10];
         input.read(&mut buf).unwrap();
-        tx.send(());
+        tx.send(()).unwrap();
     }
 }
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index b127507f048..fedc102e45d 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -16,25 +16,25 @@
 pub use self::StdioContainer::*;
 pub use self::ProcessExit::*;
 
-use prelude::*;
+use prelude::v1::*;
 
+use c_str::{CString, ToCStr};
+use collections::HashMap;
 use fmt;
-use os;
+use hash::Hash;
+use io::pipe::{PipeStream, PipePair};
 use io::{IoResult, IoError};
 use io;
 use libc;
-use c_str::CString;
-use collections::HashMap;
-use hash::Hash;
-#[cfg(windows)]
-use std::hash::sip::SipState;
-use io::pipe::{PipeStream, PipePair};
+use os;
 use path::BytesContainer;
-use thread::Thread;
-
-use sys;
+use sync::mpsc::{channel, Receiver};
 use sys::fs::FileDesc;
 use sys::process::Process as ProcessImp;
+use sys;
+use thread::Thread;
+
+#[cfg(windows)] use std::hash::sip::SipState;
 
 /// Signal a process to exit, without forcibly killing it. Corresponds to
 /// SIGTERM on unix platforms.
@@ -693,10 +693,10 @@ impl Process {
                 Some(stream) => {
                     Thread::spawn(move |:| {
                         let mut stream = stream;
-                        tx.send(stream.read_to_end())
+                        tx.send(stream.read_to_end()).unwrap();
                     }).detach();
                 }
-                None => tx.send(Ok(Vec::new()))
+                None => tx.send(Ok(Vec::new())).unwrap()
             }
             rx
         }
@@ -707,8 +707,8 @@ impl Process {
 
         Ok(ProcessOutput {
             status: status,
-            output: stdout.recv().ok().unwrap_or(Vec::new()),
-            error:  stderr.recv().ok().unwrap_or(Vec::new()),
+            output: stdout.recv().unwrap().unwrap_or(Vec::new()),
+            error:  stderr.recv().unwrap().unwrap_or(Vec::new()),
         })
     }
 
@@ -741,18 +741,19 @@ impl Drop for Process {
 
 #[cfg(test)]
 mod tests {
-    #![allow(unused_imports)]
+    use prelude::v1::*;
 
-    use super::*;
-    use io::timer::*;
-    use io::{Truncate, Write, TimedOut, timer, process, FileNotFound};
-    use prelude::{Ok, Err, spawn, range, drop, Box, Some, None, Option, Vec, Buffer};
-    use prelude::{from_str, Path, String, channel, Reader, Writer, Clone, Slice};
-    use prelude::{SliceExt, Str, StrExt, AsSlice, ToString, GenericPath};
     use io::fs::PathExtensions;
-    use time::Duration;
-    use str;
+    use io::process;
+    use io::timer::*;
+    use io::{Truncate, Write, TimedOut, timer, FileNotFound};
     use rt::running_on_valgrind;
+    use str;
+    use super::{CreatePipe};
+    use super::{InheritFd, Process, PleaseExitSignal, Command, ProcessOutput};
+    use sync::mpsc::channel;
+    use thread::Thread;
+    use time::Duration;
 
     // FIXME(#10380) these tests should not all be ignored on android.
 
@@ -1156,22 +1157,22 @@ mod tests {
     fn wait_timeout2() {
         let (tx, rx) = channel();
         let tx2 = tx.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut p = sleeper();
             p.set_timeout(Some(10));
             assert_eq!(p.wait().err().unwrap().kind, TimedOut);
             p.signal_kill().unwrap();
-            tx.send(());
+            tx.send(()).unwrap();
         });
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut p = sleeper();
             p.set_timeout(Some(10));
             assert_eq!(p.wait().err().unwrap().kind, TimedOut);
             p.signal_kill().unwrap();
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
-        rx.recv();
-        rx.recv();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
     }
 
     #[test]
diff --git a/src/libstd/io/result.rs b/src/libstd/io/result.rs
index 32965d23971..c1474650f1e 100644
--- a/src/libstd/io/result.rs
+++ b/src/libstd/io/result.rs
@@ -78,7 +78,7 @@ impl<T, A: Acceptor<T>> Acceptor<T> for IoResult<A> {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use super::super::mem::*;
     use io;
 
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index b7d069eb19e..cd991c5f884 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -117,13 +117,15 @@ pub struct StdinReaderGuard<'a> {
     inner: MutexGuard<'a, RaceBox>,
 }
 
-impl<'a> Deref<BufferedReader<StdReader>> for StdinReaderGuard<'a> {
+impl<'a> Deref for StdinReaderGuard<'a> {
+    type Target = BufferedReader<StdReader>;
+
     fn deref(&self) -> &BufferedReader<StdReader> {
         &self.inner.0
     }
 }
 
-impl<'a> DerefMut<BufferedReader<StdReader>> for StdinReaderGuard<'a> {
+impl<'a> DerefMut for StdinReaderGuard<'a> {
     fn deref_mut(&mut self) -> &mut BufferedReader<StdReader> {
         &mut self.inner.0
     }
@@ -218,7 +220,7 @@ pub fn stdin() -> StdinReader {
     static ONCE: Once = ONCE_INIT;
 
     unsafe {
-        ONCE.doit(|| {
+        ONCE.call_once(|| {
             // 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
@@ -520,8 +522,11 @@ impl Writer for StdWriter {
 
 #[cfg(test)]
 mod tests {
+    use prelude::v1::*;
+
     use super::*;
-    use prelude::*;
+    use sync::mpsc::channel;
+    use thread::Thread;
 
     #[test]
     fn smoke() {
@@ -537,7 +542,7 @@ mod tests {
 
         let (tx, rx) = channel();
         let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             set_stdout(box w);
             println!("hello!");
         });
@@ -550,7 +555,7 @@ mod tests {
 
         let (tx, rx) = channel();
         let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        spawn(move|| {
+        let _t = Thread::spawn(move || -> () {
             set_stderr(box w);
             panic!("my special message");
         });
diff --git a/src/libstd/io/tempfile.rs b/src/libstd/io/tempfile.rs
index c2b4d5a1fa9..5cf86676651 100644
--- a/src/libstd/io/tempfile.rs
+++ b/src/libstd/io/tempfile.rs
@@ -90,7 +90,7 @@ impl TempDir {
             return TempDir::new_in(&abs_tmpdir, suffix);
         }
 
-        static CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+        static CNT: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
 
         let mut attempts = 0u;
         loop {
diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs
index 40941fda79c..2f87abd0ee2 100644
--- a/src/libstd/io/test.rs
+++ b/src/libstd/io/test.rs
@@ -12,21 +12,22 @@
 
 #![macro_escape]
 
+use prelude::v1::*;
+
 use libc;
 use os;
-use prelude::*;
 use std::io::net::ip::*;
-use sync::atomic::{AtomicUint, INIT_ATOMIC_UINT, Relaxed};
+use sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Relaxed};
 
 /// Get a port number, starting at 9600, for use in tests
 pub fn next_test_port() -> u16 {
-    static NEXT_OFFSET: AtomicUint = INIT_ATOMIC_UINT;
+    static NEXT_OFFSET: AtomicUint = ATOMIC_UINT_INIT;
     base_port() + NEXT_OFFSET.fetch_add(1, Relaxed) as u16
 }
 
 /// Get a temporary path which could be the location of a unix socket
 pub fn next_test_unix() -> Path {
-    static COUNT: AtomicUint = INIT_ATOMIC_UINT;
+    static COUNT: AtomicUint = ATOMIC_UINT_INIT;
     // base port and pid are an attempt to be unique between multiple
     // test-runners of different configurations running on one
     // buildbot, the count is to be unique within this executable.
diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs
index 953effe4345..e073f76af82 100644
--- a/src/libstd/io/timer.rs
+++ b/src/libstd/io/timer.rs
@@ -15,7 +15,7 @@
 
 // FIXME: These functions take Durations but only pass ms to the backend impls.
 
-use comm::{Receiver, Sender, channel};
+use sync::mpsc::{Receiver, Sender, channel};
 use time::Duration;
 use io::IoResult;
 use sys::timer::Callback;
@@ -40,11 +40,11 @@ use sys::timer::Timer as TimerImp;
 ///
 /// let timeout = timer.oneshot(Duration::milliseconds(10));
 /// // do some work
-/// timeout.recv(); // wait for the timeout to expire
+/// timeout.recv().unwrap(); // wait for the timeout to expire
 ///
 /// let periodic = timer.periodic(Duration::milliseconds(10));
 /// loop {
-///     periodic.recv();
+///     periodic.recv().unwrap();
 ///     // this loop is only executed once every 10ms
 /// }
 /// # }
@@ -126,7 +126,7 @@ impl Timer {
     /// for _ in range(0u, 100) { /* do work */ }
     ///
     /// // blocks until 10 ms after the `oneshot` call
-    /// ten_milliseconds.recv();
+    /// ten_milliseconds.recv().unwrap();
     /// ```
     ///
     /// ```rust
@@ -136,7 +136,7 @@ impl Timer {
     /// // Incorrect, method chaining-style:
     /// let mut five_ms = Timer::new().unwrap().oneshot(Duration::milliseconds(5));
     /// // The timer object was destroyed, so this will always fail:
-    /// // five_ms.recv()
+    /// // five_ms.recv().unwrap()
     /// ```
     ///
     /// When provided a zero or negative `duration`, the message will
@@ -147,7 +147,7 @@ impl Timer {
         if in_ms_u64(duration) != 0 {
             self.inner.oneshot(in_ms_u64(duration), box TimerCallback { tx: tx });
         } else {
-            tx.send(());
+            tx.send(()).unwrap();
         }
         return rx
     }
@@ -178,13 +178,13 @@ impl Timer {
     /// for _ in range(0u, 100) { /* do work */ }
     ///
     /// // blocks until 10 ms after the `periodic` call
-    /// ten_milliseconds.recv();
+    /// ten_milliseconds.recv().unwrap();
     ///
     /// for _ in range(0u, 100) { /* do work */ }
     ///
     /// // blocks until 20 ms after the `periodic` call (*not* 10ms after the
     /// // previous `recv`)
-    /// ten_milliseconds.recv();
+    /// ten_milliseconds.recv().unwrap();
     /// ```
     ///
     /// ```rust
@@ -194,7 +194,7 @@ impl Timer {
     /// // Incorrect, method chaining-style.
     /// let mut five_ms = Timer::new().unwrap().periodic(Duration::milliseconds(5));
     /// // The timer object was destroyed, so this will always fail:
-    /// // five_ms.recv()
+    /// // five_ms.recv().unwrap()
     /// ```
     ///
     /// When provided a zero or negative `duration`, the messages will
@@ -213,7 +213,7 @@ impl Timer {
 
 impl Callback for TimerCallback {
     fn call(&mut self) {
-        let _ = self.tx.send_opt(());
+        let _ = self.tx.send(());
     }
 }
 
@@ -225,9 +225,8 @@ fn in_ms_u64(d: Duration) -> u64 {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
-
     use super::Timer;
+    use thread::Thread;
     use time::Duration;
 
     #[test]
@@ -239,7 +238,7 @@ mod test {
     #[test]
     fn test_io_timer_sleep_oneshot() {
         let mut timer = Timer::new().unwrap();
-        timer.oneshot(Duration::milliseconds(1)).recv();
+        timer.oneshot(Duration::milliseconds(1)).recv().unwrap();
     }
 
     #[test]
@@ -253,8 +252,8 @@ mod test {
         let mut timer = Timer::new().unwrap();
         let rx1 = timer.oneshot(Duration::milliseconds(10000));
         let rx = timer.oneshot(Duration::milliseconds(1));
-        rx.recv();
-        assert_eq!(rx1.recv_opt(), Err(()));
+        rx.recv().unwrap();
+        assert!(rx1.recv().is_err());
     }
 
     #[test]
@@ -263,16 +262,16 @@ mod test {
         let rx = timer.oneshot(Duration::milliseconds(100000000));
         timer.sleep(Duration::milliseconds(1)); // this should invalidate rx
 
-        assert_eq!(rx.recv_opt(), Err(()));
+        assert!(rx.recv().is_err());
     }
 
     #[test]
     fn test_io_timer_sleep_periodic() {
         let mut timer = Timer::new().unwrap();
         let rx = timer.periodic(Duration::milliseconds(1));
-        rx.recv();
-        rx.recv();
-        rx.recv();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -291,12 +290,12 @@ mod test {
         let mut timer = Timer::new().unwrap();
 
         let rx = timer.oneshot(Duration::milliseconds(1));
-        rx.recv();
-        assert!(rx.recv_opt().is_err());
+        rx.recv().unwrap();
+        assert!(rx.recv().is_err());
 
         let rx = timer.oneshot(Duration::milliseconds(1));
-        rx.recv();
-        assert!(rx.recv_opt().is_err());
+        rx.recv().unwrap();
+        assert!(rx.recv().is_err());
     }
 
     #[test]
@@ -305,20 +304,20 @@ mod test {
         let orx = timer.oneshot(Duration::milliseconds(100));
         let prx = timer.periodic(Duration::milliseconds(100));
         timer.sleep(Duration::milliseconds(1));
-        assert_eq!(orx.recv_opt(), Err(()));
-        assert_eq!(prx.recv_opt(), Err(()));
-        timer.oneshot(Duration::milliseconds(1)).recv();
+        assert!(orx.recv().is_err());
+        assert!(prx.recv().is_err());
+        timer.oneshot(Duration::milliseconds(1)).recv().unwrap();
     }
 
     #[test]
     fn period() {
         let mut timer = Timer::new().unwrap();
         let rx = timer.periodic(Duration::milliseconds(1));
-        rx.recv();
-        rx.recv();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
         let rx2 = timer.periodic(Duration::milliseconds(1));
-        rx2.recv();
-        rx2.recv();
+        rx2.recv().unwrap();
+        rx2.recv().unwrap();
     }
 
     #[test]
@@ -357,9 +356,9 @@ mod test {
         let mut timer = Timer::new().unwrap();
         let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
-        spawn(move|| {
-            let _ = timer_rx.recv_opt();
-        });
+        Thread::spawn(move|| {
+            let _ = timer_rx.recv();
+        }).detach();
 
         // when we drop the TimerWatcher we're going to destroy the channel,
         // which must wake up the task on the other end
@@ -371,9 +370,9 @@ mod test {
         let mut timer = Timer::new().unwrap();
         let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
-        spawn(move|| {
-            let _ = timer_rx.recv_opt();
-        });
+        Thread::spawn(move|| {
+            let _ = timer_rx.recv();
+        }).detach();
 
         timer.oneshot(Duration::milliseconds(1));
     }
@@ -384,9 +383,9 @@ mod test {
         let mut timer = Timer::new().unwrap();
         let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
-        spawn(move|| {
-            let _ = timer_rx.recv_opt();
-        });
+        Thread::spawn(move|| {
+            let _ = timer_rx.recv();
+        }).detach();
 
         timer.sleep(Duration::milliseconds(1));
     }
@@ -397,7 +396,7 @@ mod test {
             let mut timer = Timer::new().unwrap();
             timer.oneshot(Duration::milliseconds(1000))
         };
-        assert_eq!(rx.recv_opt(), Err(()));
+        assert!(rx.recv().is_err());
     }
 
     #[test]
@@ -406,7 +405,7 @@ mod test {
             let mut timer = Timer::new().unwrap();
             timer.periodic(Duration::milliseconds(1000))
         };
-        assert_eq!(rx.recv_opt(), Err(()));
+        assert!(rx.recv().is_err());
     }
 
     #[test]
@@ -445,34 +444,34 @@ mod test {
     fn oneshot_zero() {
         let mut timer = Timer::new().unwrap();
         let rx = timer.oneshot(Duration::milliseconds(0));
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
     fn oneshot_negative() {
         let mut timer = Timer::new().unwrap();
         let rx = timer.oneshot(Duration::milliseconds(-1000000));
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
     fn periodic_zero() {
         let mut timer = Timer::new().unwrap();
         let rx = timer.periodic(Duration::milliseconds(0));
-        rx.recv();
-        rx.recv();
-        rx.recv();
-        rx.recv();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
     }
 
     #[test]
     fn periodic_negative() {
         let mut timer = Timer::new().unwrap();
         let rx = timer.periodic(Duration::milliseconds(-1000000));
-        rx.recv();
-        rx.recv();
-        rx.recv();
-        rx.recv();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
+        rx.recv().unwrap();
     }
 
 }
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 9840412160d..38ab71c172c 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -10,7 +10,7 @@
 
 //! Utility implementations of Reader and Writer
 
-use prelude::*;
+use prelude::v1::*;
 use cmp;
 use io;
 use slice::bytes::MutableByteVector;
@@ -278,11 +278,11 @@ impl<T: Iterator<u8>> Reader for IterReader<T> {
 
 #[cfg(test)]
 mod test {
+    use prelude::v1::*;
+
     use io::{MemReader, ByRefReader};
     use io;
-    use boxed::Box;
     use super::*;
-    use prelude::{Ok, range, Vec, Buffer, Writer, Reader, ToString, AsSlice};
 
     #[test]
     fn test_limit_reader_unlimited() {
@@ -386,7 +386,7 @@ mod test {
         let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
                                    Vec::new());
         assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
-        let (_, w) = r.unwrap();
+        let (_, w) = r.into_inner();
         assert_eq!(vec!(0, 1, 2), w);
     }
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 74c387c5eea..7c8aab2b31d 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -107,6 +107,8 @@
 #![feature(macro_rules, globs, linkage, thread_local, asm)]
 #![feature(default_type_params, phase, lang_items, unsafe_destructor)]
 #![feature(slicing_syntax, unboxed_closures)]
+#![feature(old_orphan_check)]
+#![feature(associated_types)]
 
 // Don't link to std. We are std.
 #![no_std]
@@ -227,7 +229,6 @@ pub mod hash;
 pub mod task;
 pub mod thread;
 pub mod sync;
-pub mod comm;
 
 #[cfg(unix)]
 #[path = "sys/unix/mod.rs"] mod sys;
@@ -255,7 +256,7 @@ mod std {
     pub use cmp;
     pub use hash;
 
-    pub use comm; // used for select!()
+    pub use sync; // used for select!()
     pub use error; // used for try!()
     pub use fmt; // used for any formatting strings
     pub use io; // used for println!()
@@ -265,6 +266,7 @@ mod std {
     pub use cell; // used for tls!
     pub use thread_local; // used for thread_local!
     pub use kinds; // used for tls!
+    pub use ops; // used for bitflags!
 
     // The test runner calls ::std::os::args() but really wants realstd
     #[cfg(test)] pub use realstd::os as os;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index ebb64bc2f2d..63fd3209cc0 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -317,9 +317,8 @@ macro_rules! try {
 #[macro_export]
 macro_rules! vec {
     ($($x:expr),*) => ({
-        use std::slice::BoxedSliceExt;
         let xs: ::std::boxed::Box<[_]> = box [$($x),*];
-        xs.into_vec()
+        ::std::slice::SliceExt::into_vec(xs)
     });
     ($($x:expr,)*) => (vec![$($x),*])
 }
@@ -334,6 +333,7 @@ macro_rules! vec {
 ///
 /// ```
 /// use std::thread::Thread;
+/// use std::sync::mpsc::channel;
 ///
 /// let (tx1, rx1) = channel();
 /// let (tx2, rx2) = channel();
@@ -344,21 +344,21 @@ macro_rules! vec {
 /// Thread::spawn(move|| { tx2.send(calculate_the_answer()) }).detach();
 ///
 /// select! (
-///     () = rx1.recv() => println!("the long running task finished first"),
+///     _ = rx1.recv() => println!("the long running task finished first"),
 ///     answer = rx2.recv() => {
-///         println!("the answer was: {}", answer);
+///         println!("the answer was: {}", answer.unwrap());
 ///     }
 /// )
 /// ```
 ///
-/// For more information about select, see the `std::comm::Select` structure.
+/// For more information about select, see the `std::sync::mpsc::Select` structure.
 #[macro_export]
 #[experimental]
 macro_rules! select {
     (
         $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
     ) => ({
-        use std::comm::Select;
+        use std::sync::mpsc::Select;
         let sel = Select::new();
         $( let mut $rx = sel.handle(&$rx); )+
         unsafe {
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 1f76382ce8a..f2a0419e391 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -15,7 +15,7 @@
 #![allow(unsigned_negation)]
 #![doc(primitive = "f32")]
 
-use prelude::*;
+use prelude::v1::*;
 
 use intrinsics;
 use libc::c_int;
@@ -496,23 +496,25 @@ mod tests {
 
     #[test]
     fn test_real_consts() {
-        let pi: f32 = Float::pi();
-        let two_pi: f32 = Float::two_pi();
-        let frac_pi_2: f32 = Float::frac_pi_2();
-        let frac_pi_3: f32 = Float::frac_pi_3();
-        let frac_pi_4: f32 = Float::frac_pi_4();
-        let frac_pi_6: f32 = Float::frac_pi_6();
-        let frac_pi_8: f32 = Float::frac_pi_8();
-        let frac_1_pi: f32 = Float::frac_1_pi();
-        let frac_2_pi: f32 = Float::frac_2_pi();
-        let frac_2_sqrtpi: f32 = Float::frac_2_sqrtpi();
-        let sqrt2: f32 = Float::sqrt2();
-        let frac_1_sqrt2: f32 = Float::frac_1_sqrt2();
-        let e: f32 = Float::e();
-        let log2_e: f32 = Float::log2_e();
-        let log10_e: f32 = Float::log10_e();
-        let ln_2: f32 = Float::ln_2();
-        let ln_10: f32 = Float::ln_10();
+        use super::consts;
+
+        let pi: f32 = consts::PI;
+        let two_pi: f32 = consts::PI_2;
+        let frac_pi_2: f32 = consts::FRAC_PI_2;
+        let frac_pi_3: f32 = consts::FRAC_PI_3;
+        let frac_pi_4: f32 = consts::FRAC_PI_4;
+        let frac_pi_6: f32 = consts::FRAC_PI_6;
+        let frac_pi_8: f32 = consts::FRAC_PI_8;
+        let frac_1_pi: f32 = consts::FRAC_1_PI;
+        let frac_2_pi: f32 = consts::FRAC_2_PI;
+        let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRTPI;
+        let sqrt2: f32 = consts::SQRT2;
+        let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT2;
+        let e: f32 = consts::E;
+        let log2_e: f32 = consts::LOG2_E;
+        let log10_e: f32 = consts::LOG10_E;
+        let ln_2: f32 = consts::LN_2;
+        let ln_10: f32 = consts::LN_10;
 
         assert_approx_eq!(two_pi, 2f32 * pi);
         assert_approx_eq!(frac_pi_2, pi / 2f32);
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 221ecf62c05..105a8a23bd1 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -14,7 +14,7 @@
 #![allow(missing_docs)]
 #![doc(primitive = "f64")]
 
-use prelude::*;
+use prelude::v1::*;
 
 use intrinsics;
 use libc::c_int;
@@ -499,23 +499,24 @@ mod tests {
 
     #[test]
     fn test_real_consts() {
-        let pi: f64 = Float::pi();
-        let two_pi: f64 = Float::two_pi();
-        let frac_pi_2: f64 = Float::frac_pi_2();
-        let frac_pi_3: f64 = Float::frac_pi_3();
-        let frac_pi_4: f64 = Float::frac_pi_4();
-        let frac_pi_6: f64 = Float::frac_pi_6();
-        let frac_pi_8: f64 = Float::frac_pi_8();
-        let frac_1_pi: f64 = Float::frac_1_pi();
-        let frac_2_pi: f64 = Float::frac_2_pi();
-        let frac_2_sqrtpi: f64 = Float::frac_2_sqrtpi();
-        let sqrt2: f64 = Float::sqrt2();
-        let frac_1_sqrt2: f64 = Float::frac_1_sqrt2();
-        let e: f64 = Float::e();
-        let log2_e: f64 = Float::log2_e();
-        let log10_e: f64 = Float::log10_e();
-        let ln_2: f64 = Float::ln_2();
-        let ln_10: f64 = Float::ln_10();
+        use super::consts;
+        let pi: f64 = consts::PI;
+        let two_pi: f64 = consts::PI_2;
+        let frac_pi_2: f64 = consts::FRAC_PI_2;
+        let frac_pi_3: f64 = consts::FRAC_PI_3;
+        let frac_pi_4: f64 = consts::FRAC_PI_4;
+        let frac_pi_6: f64 = consts::FRAC_PI_6;
+        let frac_pi_8: f64 = consts::FRAC_PI_8;
+        let frac_1_pi: f64 = consts::FRAC_1_PI;
+        let frac_2_pi: f64 = consts::FRAC_2_PI;
+        let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRTPI;
+        let sqrt2: f64 = consts::SQRT2;
+        let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT2;
+        let e: f64 = consts::E;
+        let log2_e: f64 = consts::LOG2_E;
+        let log10_e: f64 = consts::LOG10_E;
+        let ln_2: f64 = consts::LN_2;
+        let ln_10: f64 = consts::LN_10;
 
         assert_approx_eq!(two_pi, 2.0 * pi);
         assert_approx_eq!(frac_pi_2, pi / 2f64);
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 48ff1a364e9..01aa21c692b 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -147,10 +147,8 @@ pub fn test_num<T>(ten: T, two: T) where
 
 #[cfg(test)]
 mod tests {
-    use prelude::{range, Some, None, Option, IteratorExt};
-    use super::{from_int, from_uint, from_i32, from_i64, from_u64, from_u32};
-    use super::{from_f64, from_f32, from_u16, from_i16, from_u8, from_i8, Int};
-    use super::{cast, NumCast, ToPrimitive, FromPrimitive, UnsignedInt};
+    use prelude::v1::*;
+    use super::*;
     use i8;
     use i16;
     use i32;
@@ -802,7 +800,7 @@ mod bench {
     extern crate test;
     use self::test::Bencher;
     use num::Int;
-    use prelude::*;
+    use prelude::v1::*;
 
     #[bench]
     fn bench_pow_function(b: &mut Bencher) {
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index febdf5f6118..6c64251091a 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -20,7 +20,7 @@ use char::{mod, Char};
 use num::{mod, Int, Float, ToPrimitive};
 use num::FpCategory as Fp;
 use ops::FnMut;
-use slice::{SliceExt, CloneSliceExt};
+use slice::SliceExt;
 use str::StrExt;
 use string::String;
 use vec::Vec;
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index e74f45f8f0a..b52e4fda7af 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -49,8 +49,9 @@ pub fn to_str_bytes<U, F>(n: $T, radix: uint, f: F) -> U where
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
     use num::FromStrRadix;
+    use str::from_str;
 
     #[test]
     pub fn test_from_str() {
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index df50b7f81af..615a20baf89 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -52,10 +52,9 @@ use ptr;
 use result::Result;
 use result::Result::{Err, Ok};
 use slice::{AsSlice, SliceExt};
-use slice::CloneSliceExt;
 use str::{Str, StrExt};
 use string::{String, ToString};
-use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
+use sync::atomic::{AtomicInt, ATOMIC_INT_INIT, SeqCst};
 use vec::Vec;
 
 #[cfg(unix)] use c_str::ToCStr;
@@ -596,7 +595,7 @@ pub fn last_os_error() -> String {
     error_string(errno() as uint)
 }
 
-static EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;
+static EXIT_STATUS: AtomicInt = ATOMIC_INT_INIT;
 
 /// Sets the process exit code
 ///
@@ -1427,8 +1426,9 @@ mod arch_consts {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
-    use option;
+    use prelude::v1::*;
+
+    use iter::repeat;
     use os::{env, getcwd, getenv, make_absolute};
     use os::{split_paths, join_paths, setenv, unsetenv};
     use os;
@@ -1457,7 +1457,7 @@ mod tests {
     fn test_setenv() {
         let n = make_rand_name();
         setenv(n.as_slice(), "VALUE");
-        assert_eq!(getenv(n.as_slice()), option::Option::Some("VALUE".to_string()));
+        assert_eq!(getenv(n.as_slice()), Some("VALUE".to_string()));
     }
 
     #[test]
@@ -1465,7 +1465,7 @@ mod tests {
         let n = make_rand_name();
         setenv(n.as_slice(), "VALUE");
         unsetenv(n.as_slice());
-        assert_eq!(getenv(n.as_slice()), option::Option::None);
+        assert_eq!(getenv(n.as_slice()), None);
     }
 
     #[test]
@@ -1474,9 +1474,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::Option::Some("2".to_string()));
+        assert_eq!(getenv(n.as_slice()), Some("2".to_string()));
         setenv(n.as_slice(), "");
-        assert_eq!(getenv(n.as_slice()), option::Option::Some("".to_string()));
+        assert_eq!(getenv(n.as_slice()), Some("".to_string()));
     }
 
     // Windows GetEnvironmentVariable requires some extra work to make sure
@@ -1493,7 +1493,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::Option::Some(s));
+        assert_eq!(getenv(n.as_slice()), Some(s));
     }
 
     #[test]
@@ -1530,14 +1530,14 @@ 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::Option::Some(v));
+            assert!(v2.is_none() || v2 == Some(v));
         }
     }
 
     #[test]
     fn test_env_set_get_huge() {
         let n = make_rand_name();
-        let s = "x".repeat(10000).to_string();
+        let s = repeat("x").take(10000).collect::<String>();
         setenv(n.as_slice(), s.as_slice());
         assert_eq!(getenv(n.as_slice()), Some(s));
         unsetenv(n.as_slice());
@@ -1659,8 +1659,8 @@ mod tests {
         path.push("mmap_file.tmp");
         let size = MemoryMap::granularity() * 2;
         let mut file = File::open_mode(&path, Open, ReadWrite).unwrap();
-        file.seek(size as i64, SeekSet);
-        file.write_u8(0);
+        file.seek(size as i64, SeekSet).unwrap();
+        file.write_u8(0).unwrap();
 
         let chunk = MemoryMap::new(size / 2, &[
             MapOption::MapReadable,
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index 30f3f56bc1c..731c3bbe427 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -71,8 +71,7 @@ use option::Option::{None, Some};
 use str;
 use str::{CowString, MaybeOwned, Str, StrExt};
 use string::String;
-use slice::{AsSlice, CloneSliceExt};
-use slice::{PartialEqSliceExt, SliceExt};
+use slice::{AsSlice, SliceExt};
 use vec::Vec;
 
 /// Typedef for POSIX file paths.
@@ -931,7 +930,9 @@ fn contains_nul<T: BytesContainer>(v: &T) -> bool {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
+    use c_str::ToCStr;
+    use path::{WindowsPath, PosixPath};
 
     #[test]
     fn test_cstring() {
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index bd4031e6230..6075010f3b5 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -22,8 +22,7 @@ use option::Option::{None, Some};
 use kinds::Sized;
 use str::{FromStr, Str};
 use str;
-use slice::{CloneSliceExt, Split, AsSlice, SliceConcatExt,
-            PartialEqSliceExt, SliceExt};
+use slice::{Split, AsSlice, SliceConcatExt, SliceExt};
 use vec::Vec;
 
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
@@ -448,10 +447,15 @@ static dot_dot_static: &'static [u8] = b"..";
 #[cfg(test)]
 mod tests {
     use super::*;
-    use prelude::Option::{mod, Some, None};
-    use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt};
-    use prelude::{DoubleEndedIteratorExt, Str, StrExt, ToString, GenericPath};
-    use str;
+
+    use clone::Clone;
+    use iter::{IteratorExt, DoubleEndedIteratorExt};
+    use option::Option::{mod, Some, None};
+    use path::GenericPath;
+    use slice::{AsSlice, SliceExt};
+    use str::{mod, Str, StrExt};
+    use string::ToString;
+    use vec::Vec;
 
     macro_rules! t {
         (s: $path:expr, $exp:expr) => (
@@ -1239,7 +1243,7 @@ mod bench {
     extern crate test;
     use self::test::Bencher;
     use super::*;
-    use prelude::{Clone, GenericPath};
+    use prelude::v1::{Clone, GenericPath};
 
     #[bench]
     fn join_home_dir(b: &mut Bencher) {
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 751ed4b70fb..55086ad3a23 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -1119,12 +1119,18 @@ fn prefix_len(p: Option<PathPrefix>) -> uint {
 
 #[cfg(test)]
 mod tests {
-    use super::*;
-    use prelude::Option::{mod, Some, None};
-    use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt};
-    use prelude::{DoubleEndedIteratorExt, Str, ToString, GenericPath};
     use super::PathPrefix::*;
     use super::parse_prefix;
+    use super::*;
+
+    use clone::Clone;
+    use iter::{IteratorExt, DoubleEndedIteratorExt};
+    use option::Option::{mod, Some, None};
+    use path::GenericPath;
+    use slice::{AsSlice, SliceExt};
+    use str::Str;
+    use string::ToString;
+    use vec::Vec;
 
     macro_rules! t {
         (s: $path:expr, $exp:expr) => (
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
deleted file mode 100644
index f016683e3d0..00000000000
--- a/src/libstd/prelude.rs
+++ /dev/null
@@ -1,94 +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.
-
-//! The Rust prelude
-//!
-//! Because `std` is required by most serious Rust software, it is
-//! imported at the topmost level of every crate by default, as if the
-//! first line of each crate was
-//!
-//! ```ignore
-//! extern crate std;
-//! ```
-//!
-//! This means that the contents of std can be accessed from any context
-//! with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
-//! etc.
-//!
-//! Additionally, `std` contains a `prelude` module that reexports many of the
-//! most common traits, types and functions. The contents of the prelude are
-//! imported into every *module* by default.  Implicitly, all modules behave as if
-//! they contained the following prologue:
-//!
-//! ```ignore
-//! use std::prelude::*;
-//! ```
-//!
-//! The prelude is primarily concerned with exporting *traits* that are so
-//! pervasive that it would be obnoxious to import for every use, particularly
-//! those that define methods on primitive types. It does include a few
-//! particularly useful standalone functions, like `from_str`, `range`, and
-//! `drop`, `spawn`, and `channel`.
-
-#![experimental]
-
-// Reexported core operators
-#[doc(no_inline)] pub use kinds::{Copy, Send, Sized, Sync};
-#[doc(no_inline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
-#[doc(no_inline)] pub use ops::{BitAnd, BitOr, BitXor};
-#[doc(no_inline)] pub use ops::{Drop, Deref, DerefMut};
-#[doc(no_inline)] pub use ops::{Shl, Shr};
-#[doc(no_inline)] pub use ops::{Index, IndexMut};
-#[doc(no_inline)] pub use ops::{Slice, SliceMut};
-#[doc(no_inline)] pub use ops::{Fn, FnMut, FnOnce};
-
-// Reexported functions
-#[doc(no_inline)] pub use iter::range;
-#[doc(no_inline)] pub use mem::drop;
-#[doc(no_inline)] pub use str::from_str;
-
-// Reexported types and traits
-
-#[doc(no_inline)] pub use borrow::IntoCow;
-#[doc(no_inline)] pub use c_str::ToCStr;
-#[doc(no_inline)] pub use char::{Char, UnicodeChar};
-#[doc(no_inline)] pub use clone::Clone;
-#[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
-#[doc(no_inline)] pub use cmp::{Ordering, Equiv};
-#[doc(no_inline)] pub use cmp::Ordering::{Less, Equal, Greater};
-#[doc(no_inline)] pub use iter::{FromIterator, Extend, ExactSizeIterator};
-#[doc(no_inline)] pub use iter::{Iterator, IteratorExt, DoubleEndedIterator};
-#[doc(no_inline)] pub use iter::{DoubleEndedIteratorExt, CloneIteratorExt};
-#[doc(no_inline)] pub use iter::{RandomAccessIterator, IteratorCloneExt, IteratorPairExt};
-#[doc(no_inline)] pub use iter::{IteratorOrdExt, MutableDoubleEndedIterator};
-#[doc(no_inline)] pub use num::{ToPrimitive, FromPrimitive};
-#[doc(no_inline)] pub use boxed::Box;
-#[doc(no_inline)] pub use option::Option;
-#[doc(no_inline)] pub use option::Option::{Some, None};
-#[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};
-#[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
-#[doc(no_inline)] pub use result::Result;
-#[doc(no_inline)] pub use result::Result::{Ok, Err};
-#[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude};
-#[doc(no_inline)] pub use core::prelude::{Tuple1, Tuple2, Tuple3, Tuple4};
-#[doc(no_inline)] pub use core::prelude::{Tuple5, Tuple6, Tuple7, Tuple8};
-#[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12};
-#[doc(no_inline)] pub use str::{Str, StrExt};
-#[doc(no_inline)] pub use slice::AsSlice;
-#[doc(no_inline)] pub use slice::{SliceConcatExt, PartialEqSliceExt};
-#[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt};
-#[doc(no_inline)] pub use slice::{BoxedSliceExt};
-#[doc(no_inline)] pub use string::{IntoString, String, ToString};
-#[doc(no_inline)] pub use vec::Vec;
-
-// Reexported runtime types
-#[doc(no_inline)] pub use comm::{sync_channel, channel};
-#[doc(no_inline)] pub use comm::{SyncSender, Sender, Receiver};
-#[doc(no_inline)] pub use task::spawn;
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
new file mode 100644
index 00000000000..da945b4c9fa
--- /dev/null
+++ b/src/libstd/prelude/mod.rs
@@ -0,0 +1,42 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Rust prelude
+//!
+//! Because `std` is required by most serious Rust software, it is
+//! imported at the topmost level of every crate by default, as if the
+//! first line of each crate was
+//!
+//! ```ignore
+//! extern crate std;
+//! ```
+//!
+//! This means that the contents of std can be accessed from any context
+//! with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
+//! etc.
+//!
+//! Additionally, `std` contains a `prelude` module that reexports many of the
+//! most common traits, types and functions. The contents of the prelude are
+//! imported into every *module* by default.  Implicitly, all modules behave as if
+//! they contained the following prologue:
+//!
+//! ```ignore
+//! use std::prelude::v1::*;
+//! ```
+//!
+//! The prelude is primarily concerned with exporting *traits* that are so
+//! pervasive that it would be obnoxious to import for every use, particularly
+//! those that define methods on primitive types.
+
+#[cfg(stage0)]
+pub use self::v1::*;
+
+#[stable]
+pub mod v1;
diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs
new file mode 100644
index 00000000000..cb5dfafb4a1
--- /dev/null
+++ b/src/libstd/prelude/v1.rs
@@ -0,0 +1,49 @@
+// 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.
+
+//! The first version of the prelude of the standard library.
+
+#![stable]
+
+// Reexported core operators
+#[stable] #[doc(no_inline)] pub use kinds::{Copy, Send, Sized, Sync};
+#[stable] #[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce};
+
+// Reexported functions
+#[stable] #[doc(no_inline)] pub use mem::drop;
+
+// Reexported types and traits
+
+#[stable] #[doc(no_inline)] pub use boxed::Box;
+#[stable] #[doc(no_inline)] pub use char::{Char, UnicodeChar};
+#[stable] #[doc(no_inline)] pub use clone::Clone;
+#[stable] #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
+#[stable] #[doc(no_inline)] pub use iter::CloneIteratorExt;
+#[stable] #[doc(no_inline)] pub use iter::DoubleEndedIterator;
+#[stable] #[doc(no_inline)] pub use iter::DoubleEndedIteratorExt;
+#[stable] #[doc(no_inline)] pub use iter::ExactSizeIterator;
+#[stable] #[doc(no_inline)] pub use iter::{Iterator, IteratorExt, Extend};
+#[stable] #[doc(no_inline)] pub use iter::{IteratorCloneExt, IteratorOrdExt};
+#[stable] #[doc(no_inline)] pub use iter::IteratorPairExt;
+#[stable] #[doc(no_inline)] pub use option::Option::{mod, Some, None};
+#[stable] #[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
+#[stable] #[doc(no_inline)] pub use result::Result::{mod, Ok, Err};
+#[stable] #[doc(no_inline)] pub use slice::AsSlice;
+#[stable] #[doc(no_inline)] pub use slice::{SliceExt, SliceConcatExt};
+#[stable] #[doc(no_inline)] pub use str::{Str, StrExt};
+#[stable] #[doc(no_inline)] pub use string::{String, ToString};
+#[stable] #[doc(no_inline)] pub use vec::Vec;
+
+// NB: remove when path reform lands
+#[doc(no_inline)] pub use path::{Path, GenericPath};
+// NB: remove when I/O reform lands
+#[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude};
+// NB: remove when range syntax lands
+#[doc(no_inline)] pub use iter::range;
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index f665d150f38..86b8bfc7370 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -419,7 +419,7 @@ pub fn sample<T, I: Iterator<T>, R: Rng>(rng: &mut R,
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use super::{Rng, thread_rng, random, SeedableRng, StdRng, sample};
     use iter::order;
 
@@ -615,7 +615,7 @@ static RAND_BENCH_N: u64 = 100;
 #[cfg(test)]
 mod bench {
     extern crate test;
-    use prelude::*;
+    use prelude::v1::*;
 
     use self::test::Bencher;
     use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index ca36f2d8997..9f3ac84afff 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -84,10 +84,10 @@ mod imp {
     #[cfg(all(target_os = "linux",
               any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))]
     fn is_getrandom_available() -> bool {
-        use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Relaxed};
+        use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Relaxed};
 
-        static GETRANDOM_CHECKED: AtomicBool = INIT_ATOMIC_BOOL;
-        static GETRANDOM_AVAILABLE: AtomicBool = INIT_ATOMIC_BOOL;
+        static GETRANDOM_CHECKED: AtomicBool = ATOMIC_BOOL_INIT;
+        static GETRANDOM_AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT;
 
         if !GETRANDOM_CHECKED.load(Relaxed) {
             let mut buf: [u8; 0] = [];
@@ -338,10 +338,11 @@ mod imp {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
 
-    use super::OsRng;
+    use sync::mpsc::channel;
     use rand::Rng;
+    use super::OsRng;
     use thread::Thread;
 
     #[test]
@@ -365,7 +366,7 @@ mod test {
 
             Thread::spawn(move|| {
                 // wait until all the tasks are ready to go.
-                rx.recv();
+                rx.recv().unwrap();
 
                 // deschedule to attempt to interleave things as much
                 // as possible (XXX: is this a good test?)
@@ -386,7 +387,7 @@ mod test {
 
         // start all the tasks
         for tx in txs.iter() {
-            tx.send(())
+            tx.send(()).unwrap();
         }
     }
 }
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
index 15e63aa19ea..48d7f2e7854 100644
--- a/src/libstd/rand/reader.rs
+++ b/src/libstd/rand/reader.rs
@@ -74,7 +74,7 @@ impl<R: Reader> Rng for ReaderRng<R> {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
 
     use super::ReaderRng;
     use io::MemReader;
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 98eff621ce0..4734a39c835 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -44,7 +44,7 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
           target_os = "freebsd",
           target_os = "dragonfly"))]
 mod imp {
-    use prelude::*;
+    use prelude::v1::*;
 
     use mem;
     use slice;
@@ -107,7 +107,7 @@ mod imp {
 
     #[cfg(test)]
     mod tests {
-        use prelude::*;
+        use prelude::v1::*;
         use finally::Finally;
 
         use super::*;
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 3eeb0ad3968..ae405e9400b 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -12,7 +12,7 @@
 
 #![allow(non_camel_case_types)]
 
-use prelude::*;
+use prelude::v1::*;
 
 use os;
 use sync::atomic;
@@ -22,7 +22,7 @@ pub use sys::backtrace::write;
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
 pub fn log_enabled() -> bool {
-    static ENABLED: atomic::AtomicInt = atomic::INIT_ATOMIC_INT;
+    static ENABLED: atomic::AtomicInt = atomic::ATOMIC_INT_INIT;
     match ENABLED.load(atomic::SeqCst) {
         1 => return false,
         2 => return true,
@@ -39,7 +39,7 @@ pub fn log_enabled() -> bool {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use sys_common;
     macro_rules! t { ($a:expr, $b:expr) => ({
         let mut m = Vec::new();
diff --git a/src/libstd/rt/exclusive.rs b/src/libstd/rt/exclusive.rs
deleted file mode 100644
index 88bdb29caec..00000000000
--- a/src/libstd/rt/exclusive.rs
+++ /dev/null
@@ -1,119 +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.
-
-use core::prelude::*;
-
-use cell::UnsafeCell;
-use rt::mutex;
-
-/// An OS mutex over some data.
-///
-/// This is not a safe primitive to use, it is unaware of the libgreen
-/// scheduler, as well as being easily susceptible to misuse due to the usage of
-/// the inner NativeMutex.
-///
-/// > **Note**: This type is not recommended for general use. The mutex provided
-/// >           as part of `libsync` should almost always be favored.
-pub struct Exclusive<T> {
-    lock: mutex::NativeMutex,
-    data: UnsafeCell<T>,
-}
-
-unsafe impl<T:Send> Send for Exclusive<T> { }
-
-unsafe impl<T:Send> Sync for Exclusive<T> { }
-
-/// An RAII guard returned via `lock`
-pub struct ExclusiveGuard<'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,
-    _guard: mutex::LockGuard<'a>,
-}
-
-impl<T: Send> Exclusive<T> {
-    /// Creates a new `Exclusive` which will protect the data provided.
-    pub fn new(user_data: T) -> Exclusive<T> {
-        Exclusive {
-            lock: unsafe { mutex::NativeMutex::new() },
-            data: UnsafeCell::new(user_data),
-        }
-    }
-
-    /// Acquires this lock, returning a guard which the data is accessed through
-    /// and from which that lock will be unlocked.
-    ///
-    /// This method is unsafe due to many of the same reasons that the
-    /// NativeMutex itself is unsafe.
-    pub unsafe fn lock<'a>(&'a self) -> ExclusiveGuard<'a, T> {
-        let guard = self.lock.lock();
-        let data = &mut *self.data.get();
-
-        ExclusiveGuard {
-            _data: data,
-            _guard: guard,
-        }
-    }
-}
-
-impl<'a, T: Send> ExclusiveGuard<'a, T> {
-    // The unsafety here should be ok because our loan guarantees that the lock
-    // itself is not moving
-    pub fn signal(&self) {
-        unsafe { self._guard.signal() }
-    }
-    pub fn wait(&self) {
-        unsafe { self._guard.wait() }
-    }
-}
-
-impl<'a, T: Send> Deref<T> for ExclusiveGuard<'a, T> {
-    fn deref(&self) -> &T { &*self._data }
-}
-impl<'a, T: Send> DerefMut<T> for ExclusiveGuard<'a, T> {
-    fn deref_mut(&mut self) -> &mut T { &mut *self._data }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use sync::Arc;
-    use super::Exclusive;
-    use task;
-
-    #[test]
-    fn exclusive_new_arc() {
-        unsafe {
-            let mut futures = Vec::new();
-
-            let num_tasks = 10;
-            let count = 10;
-
-            let total = Arc::new(Exclusive::new(box 0));
-
-            for _ in range(0u, num_tasks) {
-                let total = total.clone();
-                let (tx, rx) = channel();
-                futures.push(rx);
-
-                task::spawn(move || {
-                    for _ in range(0u, count) {
-                        **total.lock() += 1;
-                    }
-                    tx.send(());
-                });
-            };
-
-            for f in futures.iter_mut() { f.recv() }
-
-            assert_eq!(**total.lock(), num_tasks * count);
-        }
-    }
-}
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index e877dd5c6aa..68aaa1b3ae5 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -23,14 +23,10 @@
 
 #![allow(dead_code)]
 
-use os;
-use thunk::Thunk;
 use kinds::Send;
-use thread::Thread;
 use ops::FnOnce;
 use sys;
-use sys_common;
-use sys_common::thread_info::{mod, NewThread};
+use thunk::Thunk;
 
 // Reexport some of our utilities which are expected by other crates.
 pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
@@ -65,9 +61,14 @@ const OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
 #[cfg(not(test))]
 #[lang = "start"]
 fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
+    use prelude::v1::*;
+
     use mem;
-    use prelude::*;
+    use os;
     use rt;
+    use sys_common::thread_info::{mod, NewThread};
+    use sys_common;
+    use thread::Thread;
 
     let something_around_the_top_of_the_stack = 1;
     let addr = &something_around_the_top_of_the_stack as *const int;
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
deleted file mode 100644
index 41e91d1b6ef..00000000000
--- a/src/libstd/rt/task.rs
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright 2013-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.
-
-//! Language-level runtime services that should reasonably expected
-//! to be available 'everywhere'. Unwinding, local storage, and logging.
-//! Even a 'freestanding' Rust would likely want to implement this.
-
-pub use self::BlockedTask::*;
-use self::TaskState::*;
-
-use any::Any;
-use boxed::Box;
-use sync::Arc;
-use sync::atomic::{AtomicUint, SeqCst};
-use iter::{IteratorExt, Take};
-use kinds::marker;
-use mem;
-use ops::FnMut;
-use core::prelude::{Clone, Drop, Err, Iterator, None, Ok, Option, Send, Some};
-use core::prelude::{drop};
-use str::SendStr;
-use thunk::Thunk;
-
-use rt;
-use rt::mutex::NativeMutex;
-use rt::local::Local;
-use rt::thread::{mod, Thread};
-use sys_common::stack;
-use rt::unwind;
-use rt::unwind::Unwinder;
-
-/// State associated with Rust threads
-///
-/// This structure is currently undergoing major changes, and is
-/// likely to be move/be merged with a `Thread` structure.
-pub struct Task {
-    pub unwinder: Unwinder,
-    pub death: Death,
-    pub name: Option<SendStr>,
-
-    state: TaskState,
-    lock: NativeMutex,       // native synchronization
-    awoken: bool,            // used to prevent spurious wakeups
-
-    // This field holds the known bounds of the stack in (lo, hi) form. Not all
-    // native threads necessarily know their precise bounds, hence this is
-    // optional.
-    stack_bounds: (uint, uint),
-
-    stack_guard: uint
-}
-
-// Once a thread has entered the `Armed` state it must be destroyed via `drop`,
-// and no other method. This state is used to track this transition.
-#[deriving(PartialEq)]
-enum TaskState {
-    New,
-    Armed,
-    Destroyed,
-}
-
-pub struct TaskOpts {
-    /// Invoke this procedure with the result of the thread when it finishes.
-    pub on_exit: Option<Thunk<Result>>,
-    /// A name for the thread-to-be, for identification in panic messages
-    pub name: Option<SendStr>,
-    /// The size of the stack for the spawned thread
-    pub stack_size: Option<uint>,
-}
-
-/// Indicates the manner in which a thread exited.
-///
-/// A thread that completes without panicking is considered to exit successfully.
-///
-/// If you wish for this result's delivery to block until all
-/// children threads complete, recommend using a result future.
-pub type Result = ::core::result::Result<(), Box<Any + Send>>;
-
-/// A handle to a blocked thread. Usually this means having the Box<Task>
-/// pointer by ownership, but if the thread is killable, a killer can steal it
-/// at any time.
-pub enum BlockedTask {
-    Owned(Box<Task>),
-    Shared(Arc<AtomicUint>),
-}
-
-/// Per-thread state related to thread death, killing, panic, etc.
-pub struct Death {
-    pub on_exit: Option<Thunk<Result>>,
-}
-
-pub struct BlockedTasks {
-    inner: Arc<AtomicUint>,
-}
-
-impl Task {
-    /// Creates a new uninitialized thread.
-    pub fn new(stack_bounds: Option<(uint, uint)>, stack_guard: Option<uint>) -> Task {
-        Task {
-            unwinder: Unwinder::new(),
-            death: Death::new(),
-            state: New,
-            name: None,
-            lock: unsafe { NativeMutex::new() },
-            awoken: false,
-            // these *should* get overwritten
-            stack_bounds: stack_bounds.unwrap_or((0, 0)),
-            stack_guard: stack_guard.unwrap_or(0)
-        }
-    }
-
-    pub fn spawn<F>(opts: TaskOpts, f: F)
-        where F : FnOnce(), F : Send
-    {
-        Task::spawn_thunk(opts, Thunk::new(f))
-    }
-
-    fn spawn_thunk(opts: TaskOpts, f: Thunk) {
-        let TaskOpts { name, stack_size, on_exit } = opts;
-
-        let mut task = box Task::new(None, None);
-        task.name = name;
-        task.death.on_exit = on_exit;
-
-        let stack = stack_size.unwrap_or(rt::min_stack());
-
-        // Spawning a new OS thread guarantees that __morestack will never get
-        // triggered, but we must manually set up the actual stack bounds once
-        // this function starts executing. This raises the lower limit by a bit
-        // because by the time that this function is executing we've already
-        // consumed at least a little bit of stack (we don't know the exact byte
-        // address at which our stack started).
-        Thread::spawn_stack(stack, move|| {
-            let something_around_the_top_of_the_stack = 1;
-            let addr = &something_around_the_top_of_the_stack as *const int;
-            let my_stack = addr as uint;
-            unsafe {
-                stack::record_os_managed_stack_bounds(my_stack - stack + 1024,
-                                                      my_stack);
-            }
-            task.stack_guard = thread::current_guard_page();
-            task.stack_bounds = (my_stack - stack + 1024, my_stack);
-
-            let mut f = Some(f);
-            drop(task.run(|| { f.take().unwrap().invoke(()) }).destroy());
-        })
-    }
-
-    /// Consumes ownership of a thread, runs some code, and returns the thread back.
-    ///
-    /// This function can be used as an emulated "try/catch" to interoperate
-    /// with the rust runtime at the outermost boundary. It is not possible to
-    /// use this function in a nested fashion (a try/catch inside of another
-    /// try/catch). Invoking this function is quite cheap.
-    ///
-    /// If the closure `f` succeeds, then the returned thread can be used again
-    /// for another invocation of `run`. If the closure `f` panics then `self`
-    /// will be internally destroyed along with all of the other associated
-    /// resources of this thread. The `on_exit` callback is invoked with the
-    /// cause of panic (not returned here). This can be discovered by querying
-    /// `is_destroyed()`.
-    ///
-    /// Note that it is possible to view partial execution of the closure `f`
-    /// because it is not guaranteed to run to completion, but this function is
-    /// guaranteed to return if it panicks. Care should be taken to ensure that
-    /// stack references made by `f` are handled appropriately.
-    ///
-    /// It is invalid to call this function with a thread that has been previously
-    /// destroyed via a failed call to `run`.
-    pub fn run<F>(mut self: Box<Task>, f: F) -> Box<Task> where F: FnOnce() {
-        assert!(!self.is_destroyed(), "cannot re-use a destroyed thread");
-
-        // First, make sure that no one else is in TLS. This does not allow
-        // recursive invocations of run(). If there's no one else, then
-        // relinquish ownership of ourselves back into TLS.
-        if Local::exists(None::<Task>) {
-            panic!("cannot run a thread recursively inside another");
-        }
-        self.state = Armed;
-        Local::put(self);
-
-        // There are two primary reasons that general try/catch is unsafe. The
-        // first is that we do not support nested try/catch. The above check for
-        // an existing thread in TLS is sufficient for this invariant to be
-        // upheld. The second is that unwinding while unwinding is not defined.
-        // We take care of that by having an 'unwinding' flag in the thread
-        // itself. For these reasons, this unsafety should be ok.
-        let result = unsafe { unwind::try(f) };
-
-        // After running the closure given return the thread back out if it ran
-        // successfully, or clean up the thread if it panicked.
-        let task: Box<Task> = Local::take();
-        match result {
-            Ok(()) => task,
-            Err(cause) => { task.cleanup(Err(cause)) }
-        }
-    }
-
-    /// Destroy all associated resources of this thread.
-    ///
-    /// This function will perform any necessary clean up to prepare the thread
-    /// for destruction. It is required that this is called before a `Task`
-    /// falls out of scope.
-    ///
-    /// The returned thread cannot be used for running any more code, but it may
-    /// be used to extract the runtime as necessary.
-    pub fn destroy(self: Box<Task>) -> Box<Task> {
-        if self.is_destroyed() {
-            self
-        } else {
-            self.cleanup(Ok(()))
-        }
-    }
-
-    /// Cleans up a thread, processing the result of the thread as appropriate.
-    ///
-    /// This function consumes ownership of the thread, deallocating it once it's
-    /// done being processed. It is assumed that TLD and the local heap have
-    /// already been destroyed and/or annihilated.
-    fn cleanup(mut self: Box<Task>, result: Result) -> Box<Task> {
-        // After taking care of the data above, we need to transmit the result
-        // of this thread.
-        let what_to_do = self.death.on_exit.take();
-        Local::put(self);
-
-        // FIXME: this is running in a seriously constrained context. If this
-        //        allocates TLD then it will likely abort the runtime. Similarly,
-        //        if this panics, this will also likely abort the runtime.
-        //
-        //        This closure is currently limited to a channel send via the
-        //        standard library's thread interface, but this needs
-        //        reconsideration to whether it's a reasonable thing to let a
-        //        thread to do or not.
-        match what_to_do {
-            Some(f) => { f.invoke(result) }
-            None => { drop(result) }
-        }
-
-        // Now that we're done, we remove the thread from TLS and flag it for
-        // destruction.
-        let mut task: Box<Task> = Local::take();
-        task.state = Destroyed;
-        return task;
-    }
-
-    /// Queries whether this can be destroyed or not.
-    pub fn is_destroyed(&self) -> bool { self.state == Destroyed }
-
-    /// Deschedules the current thread, invoking `f` `amt` times. It is not
-    /// recommended to use this function directly, but rather communication
-    /// primitives in `std::comm` should be used.
-    //
-    // This function gets a little interesting. There are a few safety and
-    // ownership violations going on here, but this is all done in the name of
-    // shared state. Additionally, all of the violations are protected with a
-    // mutex, so in theory there are no races.
-    //
-    // The first thing we need to do is to get a pointer to the thread's internal
-    // mutex. This address will not be changing (because the thread is allocated
-    // on the heap). We must have this handle separately because the thread will
-    // have its ownership transferred to the given closure. We're guaranteed,
-    // however, that this memory will remain valid because *this* is the current
-    // thread's execution thread.
-    //
-    // The next weird part is where ownership of the thread actually goes. We
-    // relinquish it to the `f` blocking function, but upon returning this
-    // function needs to replace the thread back in TLS. There is no communication
-    // from the wakeup thread back to this thread about the thread pointer, and
-    // there's really no need to. In order to get around this, we cast the thread
-    // to a `uint` which is then used at the end of this function to cast back
-    // to a `Box<Task>` object. Naturally, this looks like it violates
-    // ownership semantics in that there may be two `Box<Task>` objects.
-    //
-    // The fun part is that the wakeup half of this implementation knows to
-    // "forget" the thread on the other end. This means that the awakening half of
-    // things silently relinquishes ownership back to this thread, but not in a
-    // way that the compiler can understand. The thread's memory is always valid
-    // for both threads because these operations are all done inside of a mutex.
-    //
-    // You'll also find that if blocking fails (the `f` function hands the
-    // BlockedTask back to us), we will `mem::forget` the handles. The
-    // reasoning for this is the same logic as above in that the thread silently
-    // transfers ownership via the `uint`, not through normal compiler
-    // semantics.
-    //
-    // On a mildly unrelated note, it should also be pointed out that OS
-    // condition variables are susceptible to spurious wakeups, which we need to
-    // be ready for. In order to accommodate for this fact, we have an extra
-    // `awoken` field which indicates whether we were actually woken up via some
-    // invocation of `reawaken`. This flag is only ever accessed inside the
-    // lock, so there's no need to make it atomic.
-    pub fn deschedule<F>(mut self: Box<Task>, times: uint, mut f: F) where
-        F: FnMut(BlockedTask) -> ::core::result::Result<(), BlockedTask>,
-    {
-        unsafe {
-            let me = &mut *self as *mut Task;
-            let task = BlockedTask::block(self);
-
-            if times == 1 {
-                let guard = (*me).lock.lock();
-                (*me).awoken = false;
-                match f(task) {
-                    Ok(()) => {
-                        while !(*me).awoken {
-                            guard.wait();
-                        }
-                    }
-                    Err(task) => { mem::forget(task.wake()); }
-                }
-            } else {
-                let iter = task.make_selectable(times);
-                let guard = (*me).lock.lock();
-                (*me).awoken = false;
-
-                // Apply the given closure to all of the "selectable threads",
-                // bailing on the first one that produces an error. Note that
-                // care must be taken such that when an error is occurred, we
-                // may not own the thread, so we may still have to wait for the
-                // thread to become available. In other words, if thread.wake()
-                // returns `None`, then someone else has ownership and we must
-                // wait for their signal.
-                match iter.map(f).filter_map(|a| a.err()).next() {
-                    None => {}
-                    Some(task) => {
-                        match task.wake() {
-                            Some(task) => {
-                                mem::forget(task);
-                                (*me).awoken = true;
-                            }
-                            None => {}
-                        }
-                    }
-                }
-                while !(*me).awoken {
-                    guard.wait();
-                }
-            }
-            // put the thread back in TLS, and everything is as it once was.
-            Local::put(mem::transmute(me));
-        }
-    }
-
-    /// Wakes up a previously blocked thread. This function can only be
-    /// called on threads that were previously blocked in `deschedule`.
-    //
-    // See the comments on `deschedule` for why the thread is forgotten here, and
-    // why it's valid to do so.
-    pub fn reawaken(mut self: Box<Task>) {
-        unsafe {
-            let me = &mut *self as *mut Task;
-            mem::forget(self);
-            let guard = (*me).lock.lock();
-            (*me).awoken = true;
-            guard.signal();
-        }
-    }
-
-    /// Yields control of this thread to another thread. This function will
-    /// eventually return, but possibly not immediately. This is used as an
-    /// opportunity to allow other threads a chance to run.
-    pub fn yield_now() {
-        Thread::yield_now();
-    }
-
-    /// Returns the stack bounds for this thread in (lo, hi) format. The stack
-    /// bounds may not be known for all threads, so the return value may be
-    /// `None`.
-    pub fn stack_bounds(&self) -> (uint, uint) {
-        self.stack_bounds
-    }
-
-    /// Returns the stack guard for this thread, if known.
-    pub fn stack_guard(&self) -> Option<uint> {
-        if self.stack_guard != 0 {
-            Some(self.stack_guard)
-        } else {
-            None
-        }
-    }
-
-    /// Consume this thread, flagging it as a candidate for destruction.
-    ///
-    /// This function is required to be invoked to destroy a thread. A thread
-    /// destroyed through a normal drop will abort.
-    pub fn drop(mut self) {
-        self.state = Destroyed;
-    }
-}
-
-impl Drop for Task {
-    fn drop(&mut self) {
-        rtdebug!("called drop for a thread: {}", self as *mut Task as uint);
-        rtassert!(self.state != Armed);
-    }
-}
-
-impl TaskOpts {
-    pub fn new() -> TaskOpts {
-        TaskOpts { on_exit: None, name: None, stack_size: None }
-    }
-}
-
-impl Iterator<BlockedTask> for BlockedTasks {
-    fn next(&mut self) -> Option<BlockedTask> {
-        Some(Shared(self.inner.clone()))
-    }
-}
-
-impl BlockedTask {
-    /// Returns Some if the thread was successfully woken; None if already killed.
-    pub fn wake(self) -> Option<Box<Task>> {
-        match self {
-            Owned(task) => Some(task),
-            Shared(arc) => {
-                match arc.swap(0, SeqCst) {
-                    0 => None,
-                    n => Some(unsafe { mem::transmute(n) }),
-                }
-            }
-        }
-    }
-
-    /// Reawakens this thread if ownership is acquired. If finer-grained control
-    /// is desired, use `wake` instead.
-    pub fn reawaken(self) {
-        self.wake().map(|t| t.reawaken());
-    }
-
-    // This assertion has two flavours because the wake involves an atomic op.
-    // In the faster version, destructors will panic dramatically instead.
-    #[cfg(not(test))] pub fn trash(self) { }
-    #[cfg(test)]      pub fn trash(self) { assert!(self.wake().is_none()); }
-
-    /// Create a blocked thread, unless the thread was already killed.
-    pub fn block(task: Box<Task>) -> BlockedTask {
-        Owned(task)
-    }
-
-    /// Converts one blocked thread handle to a list of many handles to the same.
-    pub fn make_selectable(self, num_handles: uint) -> Take<BlockedTasks> {
-        let arc = match self {
-            Owned(task) => {
-                let flag = unsafe { AtomicUint::new(mem::transmute(task)) };
-                Arc::new(flag)
-            }
-            Shared(arc) => arc.clone(),
-        };
-        BlockedTasks{ inner: arc }.take(num_handles)
-    }
-
-    /// Convert to an unsafe uint value. Useful for storing in a pipe's state
-    /// flag.
-    #[inline]
-    pub unsafe fn cast_to_uint(self) -> uint {
-        match self {
-            Owned(task) => {
-                let blocked_task_ptr: uint = mem::transmute(task);
-                rtassert!(blocked_task_ptr & 0x1 == 0);
-                blocked_task_ptr
-            }
-            Shared(arc) => {
-                let blocked_task_ptr: uint = mem::transmute(box arc);
-                rtassert!(blocked_task_ptr & 0x1 == 0);
-                blocked_task_ptr | 0x1
-            }
-        }
-    }
-
-    /// Convert from an unsafe uint value. Useful for retrieving a pipe's state
-    /// flag.
-    #[inline]
-    pub unsafe fn cast_from_uint(blocked_task_ptr: uint) -> BlockedTask {
-        if blocked_task_ptr & 0x1 == 0 {
-            Owned(mem::transmute(blocked_task_ptr))
-        } else {
-            let ptr: Box<Arc<AtomicUint>> =
-                mem::transmute(blocked_task_ptr & !1);
-            Shared(*ptr)
-        }
-    }
-}
-
-impl Death {
-    pub fn new() -> Death {
-        Death { on_exit: None }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use prelude::*;
-    use task;
-    use rt::unwind;
-
-    #[test]
-    fn unwind() {
-        let result = task::try(move|| ());
-        rtdebug!("trying first assert");
-        assert!(result.is_ok());
-        let result = task::try(move|| -> () panic!());
-        rtdebug!("trying second assert");
-        assert!(result.is_err());
-    }
-
-    #[test]
-    fn rng() {
-        use rand::{StdRng, Rng};
-        let mut r = StdRng::new().ok().unwrap();
-        let _ = r.next_u32();
-    }
-
-    #[test]
-    fn comm_stream() {
-        let (tx, rx) = channel();
-        tx.send(10i);
-        assert!(rx.recv() == 10);
-    }
-
-    #[test]
-    fn comm_shared_chan() {
-        let (tx, rx) = channel();
-        tx.send(10i);
-        assert!(rx.recv() == 10);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_begin_unwind() {
-        use rt::unwind::begin_unwind;
-        begin_unwind("cause", &(file!(), line!()))
-    }
-
-    #[test]
-    fn drop_new_task_ok() {
-        drop(Task::new(None, None));
-    }
-
-    // Thread blocking tests
-
-    #[test]
-    fn block_and_wake() {
-        let task = box Task::new(None, None);
-        let task = BlockedTask::block(task).wake().unwrap();
-        task.drop();
-    }
-}
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index e0c512706e6..6f6be2e111d 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -57,7 +57,7 @@
 //!
 //! Currently Rust uses unwind runtime provided by libgcc.
 
-use prelude::*;
+use prelude::v1::*;
 
 use any::Any;
 use cell::Cell;
@@ -84,15 +84,15 @@ pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: uint);
 // For more information, see below.
 const MAX_CALLBACKS: uint = 16;
 static CALLBACKS: [atomic::AtomicUint; MAX_CALLBACKS] =
-        [atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
-         atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
-         atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
-         atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
-         atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
-         atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
-         atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
-         atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT];
-static CALLBACK_CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+        [atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT,
+         atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT,
+         atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT,
+         atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT,
+         atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT,
+         atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT,
+         atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT,
+         atomic::ATOMIC_UINT_INIT, atomic::ATOMIC_UINT_INIT];
+static CALLBACK_CNT: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
 
 thread_local! { static PANICKING: Cell<bool> = Cell::new(false) }
 
@@ -493,27 +493,16 @@ pub extern fn rust_begin_unwind(msg: fmt::Arguments,
 /// the actual formatting into this shared place.
 #[inline(never)] #[cold]
 pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
-    use fmt::FormatWriter;
+    use fmt::Writer;
 
     // We do two allocations here, unfortunately. But (a) they're
     // required with the current scheme, and (b) we don't handle
     // panic + OOM properly anyway (see comment in begin_unwind
     // below).
 
-    struct VecWriter<'a> { v: &'a mut Vec<u8> }
-
-    impl<'a> fmt::FormatWriter for VecWriter<'a> {
-        fn write(&mut self, buf: &[u8]) -> fmt::Result {
-            self.v.push_all(buf);
-            Ok(())
-        }
-    }
-
-    let mut v = Vec::new();
-    let _ = write!(&mut VecWriter { v: &mut v }, "{}", msg);
-
-    let msg = box String::from_utf8_lossy(v.as_slice()).into_owned();
-    begin_unwind_inner(msg, file_line)
+    let mut s = String::new();
+    let _ = write!(&mut s, "{}", msg);
+    begin_unwind_inner(box s, file_line)
 }
 
 /// This is the entry point of unwinding for panic!() and assert!().
@@ -544,7 +533,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
     // Make sure the default failure handler is registered before we look at the
     // callbacks.
     static INIT: Once = ONCE_INIT;
-    INIT.doit(|| unsafe { register(failure::on_fail); });
+    INIT.call_once(|| unsafe { register(failure::on_fail); });
 
     // First, invoke call the user-defined callbacks triggered on thread panic.
     //
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index fee86e33455..09859cab536 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -10,13 +10,12 @@
 //
 // ignore-lexer-test FIXME #15677
 
-use prelude::*;
+use prelude::v1::*;
 
 use cmp;
 use fmt;
 use intrinsics;
-use libc::uintptr_t;
-use libc;
+use libc::{mod, uintptr_t};
 use os;
 use slice;
 use str;
@@ -47,7 +46,7 @@ pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
 }
 
 pub fn min_stack() -> uint {
-    static MIN: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+    static MIN: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
     match MIN.load(atomic::SeqCst) {
         0 => {}
         n => return n - 1,
@@ -96,8 +95,8 @@ pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
 #[allow(non_upper_case_globals)]
 pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);
 
-impl fmt::FormatWriter for Stdio {
-    fn write(&mut self, data: &[u8]) -> fmt::Result {
+impl Stdio {
+    pub fn write_bytes(&mut self, data: &[u8]) {
         #[cfg(unix)]
         type WriteLen = libc::size_t;
         #[cfg(windows)]
@@ -108,6 +107,12 @@ impl fmt::FormatWriter for Stdio {
                         data.as_ptr() as *const libc::c_void,
                         data.len() as WriteLen);
         }
+    }
+}
+
+impl fmt::Writer for Stdio {
+    fn write_str(&mut self, data: &str) -> fmt::Result {
+        self.write_bytes(data.as_bytes());
         Ok(()) // yes, we're lying
     }
 }
@@ -117,16 +122,16 @@ pub fn dumb_print(args: fmt::Arguments) {
 }
 
 pub fn abort(args: fmt::Arguments) -> ! {
-    use fmt::FormatWriter;
+    use fmt::Writer;
 
     struct BufWriter<'a> {
         buf: &'a mut [u8],
         pos: uint,
     }
-    impl<'a> FormatWriter for BufWriter<'a> {
-        fn write(&mut self, bytes: &[u8]) -> fmt::Result {
+    impl<'a> fmt::Writer for BufWriter<'a> {
+        fn write_str(&mut self, bytes: &str) -> fmt::Result {
             let left = self.buf.slice_from_mut(self.pos);
-            let to_write = bytes[..cmp::min(bytes.len(), left.len())];
+            let to_write = bytes.as_bytes()[..cmp::min(bytes.len(), left.len())];
             slice::bytes::copy_memory(left, to_write);
             self.pos += to_write.len();
             Ok(())
diff --git a/src/libstd/sync/atomic.rs b/src/libstd/sync/atomic.rs
index 18c917aca8a..d4d7607bde3 100644
--- a/src/libstd/sync/atomic.rs
+++ b/src/libstd/sync/atomic.rs
@@ -86,15 +86,15 @@
 //! Keep a global count of live tasks:
 //!
 //! ```
-//! use std::sync::atomic::{AtomicUint, SeqCst, INIT_ATOMIC_UINT};
+//! use std::sync::atomic::{AtomicUint, SeqCst, ATOMIC_UINT_INIT};
 //!
-//! static GLOBAL_TASK_COUNT: AtomicUint = INIT_ATOMIC_UINT;
+//! static GLOBAL_TASK_COUNT: AtomicUint = ATOMIC_UINT_INIT;
 //!
 //! let old_task_count = GLOBAL_TASK_COUNT.fetch_add(1, SeqCst);
 //! println!("live tasks: {}", old_task_count + 1);
 //! ```
 
-#![allow(deprecated)]
+#![stable]
 
 use alloc::boxed::Box;
 use core::mem;
@@ -102,6 +102,7 @@ use core::prelude::{Send, Drop, None, Option, Some};
 
 pub use core::atomic::{AtomicBool, AtomicInt, AtomicUint, AtomicPtr};
 pub use core::atomic::{INIT_ATOMIC_BOOL, INIT_ATOMIC_INT, INIT_ATOMIC_UINT};
+pub use core::atomic::{ATOMIC_BOOL_INIT, ATOMIC_INT_INIT, ATOMIC_UINT_INIT};
 pub use core::atomic::fence;
 pub use core::atomic::Ordering::{mod, Relaxed, Release, Acquire, AcqRel, SeqCst};
 
@@ -116,6 +117,7 @@ pub struct AtomicOption<T> {
     p: AtomicUint,
 }
 
+#[allow(deprecated)]
 impl<T: Send> AtomicOption<T> {
     /// Create a new `AtomicOption`
     pub fn new(p: Box<T>) -> AtomicOption<T> {
@@ -180,7 +182,7 @@ impl<T: Send> Drop for AtomicOption<T> {
 
 #[cfg(test)]
 mod test {
-    use prelude::{Some, None};
+    use prelude::v1::*;
     use super::*;
 
     #[test]
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs
index 4091f0df395..bf5da3e7cba 100644
--- a/src/libstd/sync/barrier.rs
+++ b/src/libstd/sync/barrier.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use kinds::{Send, Sync};
 use sync::{Mutex, Condvar};
 
 /// A barrier enables multiple tasks to synchronize the beginning
@@ -30,29 +29,32 @@ use sync::{Mutex, Condvar};
 ///     }).detach();
 /// }
 /// ```
+#[stable]
 pub struct Barrier {
     lock: Mutex<BarrierState>,
     cvar: Condvar,
     num_threads: uint,
 }
 
-unsafe impl Send for Barrier {}
-unsafe impl Sync for Barrier {}
-
 // The inner state of a double barrier
 struct BarrierState {
     count: uint,
     generation_id: uint,
 }
 
-unsafe impl Send for BarrierState {}
-unsafe impl Sync for BarrierState {}
+/// A result returned from wait.
+///
+/// Currently this opaque structure only has one method, `.is_leader()`. Only
+/// one thread will receive a result that will return `true` from this function.
+#[allow(missing_copy_implementations)]
+pub struct BarrierWaitResult(bool);
 
 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`.
+    #[stable]
     pub fn new(n: uint) -> Barrier {
         Barrier {
             lock: Mutex::new(BarrierState {
@@ -68,7 +70,13 @@ impl Barrier {
     ///
     /// Barriers are re-usable after all threads have rendezvoused once, and can
     /// be used continuously.
-    pub fn wait(&self) {
+    ///
+    /// A single (arbitrary) thread will receive a `BarrierWaitResult` that
+    /// returns `true` from `is_leader` when returning from this function, and
+    /// all other threads will receive a result that will return `false` from
+    /// `is_leader`
+    #[stable]
+    pub fn wait(&self) -> BarrierWaitResult {
         let mut lock = self.lock.lock().unwrap();
         let local_gen = lock.generation_id;
         lock.count += 1;
@@ -79,46 +87,64 @@ impl Barrier {
                   lock.count < self.num_threads {
                 lock = self.cvar.wait(lock).unwrap();
             }
+            BarrierWaitResult(false)
         } else {
             lock.count = 0;
             lock.generation_id += 1;
             self.cvar.notify_all();
+            BarrierWaitResult(true)
         }
     }
 }
 
+impl BarrierWaitResult {
+    /// Return whether this thread from `wait` is the "leader thread".
+    ///
+    /// Only one thread will have `true` returned from their result, all other
+    /// threads will have `false` returned.
+    #[stable]
+    pub fn is_leader(&self) -> bool { self.0 }
+}
+
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
 
     use sync::{Arc, Barrier};
-    use comm::Empty;
+    use sync::mpsc::{channel, TryRecvError};
+    use thread::Thread;
 
     #[test]
     fn test_barrier() {
-        let barrier = Arc::new(Barrier::new(10));
+        const N: uint = 10;
+
+        let barrier = Arc::new(Barrier::new(N));
         let (tx, rx) = channel();
 
-        for _ in range(0u, 9) {
+        for _ in range(0u, N - 1) {
             let c = barrier.clone();
             let tx = tx.clone();
-            spawn(move|| {
-                c.wait();
-                tx.send(true);
-            });
+            Thread::spawn(move|| {
+                tx.send(c.wait().is_leader()).unwrap();
+            }).detach();
         }
 
         // 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,
+            Err(TryRecvError::Empty) => true,
             _ => false,
         });
 
-        barrier.wait();
+        let mut leader_found = barrier.wait().is_leader();
+
         // Now, the barrier is cleared and we should get data.
-        for _ in range(0u, 9) {
-            rx.recv();
+        for _ in range(0u, N - 1) {
+            if rx.recv().unwrap() {
+                assert!(!leader_found);
+                leader_found = true;
+            }
         }
+        assert!(leader_found);
     }
 }
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 15faf5be258..19b8f5e62cf 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 
 use sync::atomic::{mod, AtomicUint};
 use sync::poison::{mod, LockResult};
@@ -88,7 +88,7 @@ unsafe impl Sync for StaticCondvar {}
 #[unstable = "may be merged with Condvar in the future"]
 pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
     inner: sys::CONDVAR_INIT,
-    mutex: atomic::INIT_ATOMIC_UINT,
+    mutex: atomic::ATOMIC_UINT_INIT,
 };
 
 impl Condvar {
@@ -279,11 +279,13 @@ impl StaticCondvar {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
 
-    use time::Duration;
     use super::{StaticCondvar, CONDVAR_INIT};
+    use sync::mpsc::channel;
     use sync::{StaticMutex, MUTEX_INIT, Condvar, Mutex, Arc};
+    use thread::Thread;
+    use time::Duration;
 
     #[test]
     fn smoke() {
@@ -306,7 +308,7 @@ mod tests {
         static M: StaticMutex = MUTEX_INIT;
 
         let g = M.lock().unwrap();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _g = M.lock().unwrap();
             C.notify_one();
         });
@@ -324,30 +326,30 @@ mod tests {
         for _ in range(0, N) {
             let data = data.clone();
             let tx = tx.clone();
-            spawn(move|| {
+            Thread::spawn(move|| {
                 let &(ref lock, ref cond) = &*data;
                 let mut cnt = lock.lock().unwrap();
                 *cnt += 1;
                 if *cnt == N {
-                    tx.send(());
+                    tx.send(()).unwrap();
                 }
                 while *cnt != 0 {
                     cnt = cond.wait(cnt).unwrap();
                 }
-                tx.send(());
-            });
+                tx.send(()).unwrap();
+            }).detach();
         }
         drop(tx);
 
         let &(ref lock, ref cond) = &*data;
-        rx.recv();
+        rx.recv().unwrap();
         let mut cnt = lock.lock().unwrap();
         *cnt = 0;
         cond.notify_all();
         drop(cnt);
 
         for _ in range(0, N) {
-            rx.recv();
+            rx.recv().unwrap();
         }
     }
 
@@ -359,7 +361,7 @@ mod tests {
         let g = M.lock().unwrap();
         let (g, success) = C.wait_timeout(g, Duration::nanoseconds(1000)).unwrap();
         assert!(!success);
-        spawn(move|| {
+        let _t = Thread::spawn(move || {
             let _g = M.lock().unwrap();
             C.notify_one();
         });
@@ -377,14 +379,13 @@ mod tests {
         static C: StaticCondvar = CONDVAR_INIT;
 
         let mut g = M1.lock().unwrap();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _g = M1.lock().unwrap();
             C.notify_one();
         });
         g = C.wait(g).unwrap();
         drop(g);
 
-        C.wait(M2.lock().unwrap()).unwrap();
-
+        let _ = C.wait(M2.lock().unwrap()).unwrap();
     }
 }
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index 51899a87a32..e5245251ea8 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! A type representing values that may be computed concurrently and operations for working with
-//! them.
+//! A type representing values that may be computed concurrently and operations
+//! for working with them.
 //!
 //! # Example
 //!
@@ -23,12 +23,15 @@
 //! ```
 
 #![allow(missing_docs)]
+#![unstable = "futures as-is have yet to be deeply reevaluated with recent \
+               core changes to Rust's synchronization story, and will likely \
+               become stable in the future but are unstable until that time"]
 
 use core::prelude::*;
 use core::mem::replace;
 
 use self::FutureState::*;
-use comm::{Receiver, channel};
+use sync::mpsc::{Receiver, channel};
 use thunk::{Thunk};
 use thread::Thread;
 
@@ -122,8 +125,8 @@ impl<A:Send> Future<A> {
          * waiting for the result to be received on the port.
          */
 
-        Future::from_fn(move|:| {
-            rx.recv()
+        Future::from_fn(move |:| {
+            rx.recv().unwrap()
         })
     }
 
@@ -141,7 +144,7 @@ impl<A:Send> Future<A> {
 
         Thread::spawn(move |:| {
             // Don't panic if the other end has hung up
-            let _ = tx.send_opt(blk());
+            let _ = tx.send(blk());
         }).detach();
 
         Future::from_receiver(rx)
@@ -150,9 +153,10 @@ impl<A:Send> Future<A> {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
+    use sync::mpsc::channel;
     use sync::Future;
-    use task;
+    use thread::Thread;
 
     #[test]
     fn test_from_value() {
@@ -163,7 +167,7 @@ mod test {
     #[test]
     fn test_from_receiver() {
         let (tx, rx) = channel();
-        tx.send("whale".to_string());
+        tx.send("whale".to_string()).unwrap();
         let mut f = Future::from_receiver(rx);
         assert_eq!(f.get(), "whale");
     }
@@ -183,7 +187,7 @@ mod test {
     #[test]
     fn test_interface_unwrap() {
         let f = Future::from_value("fail".to_string());
-        assert_eq!(f.unwrap(), "fail");
+        assert_eq!(f.into_inner(), "fail");
     }
 
     #[test]
@@ -210,10 +214,10 @@ mod test {
         let expected = "schlorf";
         let (tx, rx) = channel();
         let f = Future::spawn(move|| { expected });
-        task::spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut f = f;
-            tx.send(f.get());
+            tx.send(f.get()).unwrap();
         });
-        assert_eq!(rx.recv(), expected);
+        assert_eq!(rx.recv().unwrap(), expected);
     }
 }
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index 092acc7ff25..c09c3b45d3e 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -26,13 +26,15 @@ pub use self::rwlock::{RWLockReadGuard, RWLockWriteGuard};
 pub use self::condvar::{Condvar, StaticCondvar, CONDVAR_INIT};
 pub use self::once::{Once, ONCE_INIT};
 pub use self::semaphore::{Semaphore, SemaphoreGuard};
-pub use self::barrier::Barrier;
+pub use self::barrier::{Barrier, BarrierWaitResult};
 pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
 
 pub use self::future::Future;
 pub use self::task_pool::TaskPool;
 
 pub mod atomic;
+pub mod mpsc;
+
 mod barrier;
 mod condvar;
 mod future;
diff --git a/src/libstd/comm/blocking.rs b/src/libstd/sync/mpsc/blocking.rs
index 412b7161305..a5299012723 100644
--- a/src/libstd/comm/blocking.rs
+++ b/src/libstd/sync/mpsc/blocking.rs
@@ -11,7 +11,7 @@
 //! Generic support for building blocking abstractions.
 
 use thread::Thread;
-use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Ordering};
+use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
 use sync::Arc;
 use kinds::{Sync, Send};
 use kinds::marker::{NoSend, NoSync};
@@ -40,7 +40,7 @@ pub struct WaitToken {
 pub fn tokens() -> (WaitToken, SignalToken) {
     let inner = Arc::new(Inner {
         thread: Thread::current(),
-        woken: INIT_ATOMIC_BOOL,
+        woken: ATOMIC_BOOL_INIT,
     });
     let wait_token = WaitToken {
         inner: inner.clone(),
diff --git a/src/libstd/comm/mod.rs b/src/libstd/sync/mpsc/mod.rs
index a405627aecc..413675f26d5 100644
--- a/src/libstd/comm/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -8,12 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Communication primitives for concurrent tasks
-//!
-//! Rust makes it very difficult to share data among tasks to prevent race
-//! conditions and to improve parallelism, but there is often a need for
-//! communication between concurrent tasks. The primitives defined in this
-//! module are the building blocks for synchronization in rust.
+//! Multi-producer, single-consumer communication primitives threads
 //!
 //! This module provides message-based communication over channels, concretely
 //! defined among three types:
@@ -23,12 +18,10 @@
 //! * `Receiver`
 //!
 //! A `Sender` or `SyncSender` is used to send data to a `Receiver`. Both
-//! senders are clone-able such that many tasks can send simultaneously to one
-//! receiver.  These channels are *task blocking*, not *thread blocking*. This
-//! means that if one task is blocked on a channel, other tasks can continue to
-//! make progress.
+//! senders are clone-able (multi-producer) such that many threads can send
+//! simultaneously to one receiver (single-consumer).  These channels are
 //!
-//! Rust channels come in one of two flavors:
+//! These channels come in two flavors:
 //!
 //! 1. An asynchronous, infinitely buffered channel. The `channel()` function
 //!    will return a `(Sender, Receiver)` tuple where all sends will be
@@ -43,36 +36,39 @@
 //!    "rendezvous" channel where each sender atomically hands off a message to
 //!    a receiver.
 //!
-//! ## Panic Propagation
+//! ## Disconnection
 //!
-//! In addition to being a core primitive for communicating in rust, channels
-//! are the points at which panics are propagated among tasks.  Whenever the one
-//! half of channel is closed, the other half will have its next operation
-//! `panic!`. The purpose of this is to allow propagation of panics among tasks
-//! that are linked to one another via channels.
+//! The send and receive operations on channels will all return a `Result`
+//! indicating whether the operation succeeded or not. An unsuccessful operation
+//! is normally indicative of the other half of a channel having "hung up" by
+//! being dropped in its corresponding thread.
 //!
-//! There are methods on both of senders and receivers to perform their
-//! respective operations without panicking, however.
+//! Once half of a channel has been deallocated, most operations can no longer
+//! continue to make progress, so `Err` will be returned. Many applications will
+//! continue to `unwrap()` the results returned from this module, instigating a
+//! propagation of failure among threads if one unexpectedly dies.
 //!
-//! # Example
+//! # Examples
 //!
 //! Simple usage:
 //!
 //! ```
 //! use std::thread::Thread;
+//! use std::sync::mpsc::channel;
 //!
 //! // Create a simple streaming channel
 //! let (tx, rx) = channel();
 //! Thread::spawn(move|| {
-//!     tx.send(10i);
+//!     tx.send(10i).unwrap();
 //! }).detach();
-//! assert_eq!(rx.recv(), 10i);
+//! assert_eq!(rx.recv().unwrap(), 10i);
 //! ```
 //!
 //! Shared usage:
 //!
 //! ```
 //! use std::thread::Thread;
+//! use std::sync::mpsc::channel;
 //!
 //! // Create a shared channel that can be sent along from many threads
 //! // where tx is the sending half (tx for transmission), and rx is the receiving
@@ -81,37 +77,40 @@
 //! for i in range(0i, 10i) {
 //!     let tx = tx.clone();
 //!     Thread::spawn(move|| {
-//!         tx.send(i);
+//!         tx.send(i).unwrap();
 //!     }).detach()
 //! }
 //!
 //! for _ in range(0i, 10i) {
-//!     let j = rx.recv();
+//!     let j = rx.recv().unwrap();
 //!     assert!(0 <= j && j < 10);
 //! }
 //! ```
 //!
 //! Propagating panics:
 //!
-//! ```should_fail
-//! // The call to recv() will panic!() because the channel has already hung
-//! // up (or been deallocated)
+//! ```
+//! use std::sync::mpsc::channel;
+//!
+//! // The call to recv() will return an error because the channel has already
+//! // hung up (or been deallocated)
 //! let (tx, rx) = channel::<int>();
 //! drop(tx);
-//! rx.recv();
+//! assert!(rx.recv().is_err());
 //! ```
 //!
 //! Synchronous channels:
 //!
 //! ```
 //! use std::thread::Thread;
+//! use std::sync::mpsc::sync_channel;
 //!
 //! let (tx, rx) = sync_channel::<int>(0);
 //! Thread::spawn(move|| {
 //!     // This will wait for the parent task to start receiving
-//!     tx.send(53);
+//!     tx.send(53).unwrap();
 //! }).detach();
-//! rx.recv();
+//! rx.recv().unwrap();
 //! ```
 //!
 //! Reading from a channel with a timeout requires to use a Timer together
@@ -120,6 +119,7 @@
 //! after 10 seconds no matter what:
 //!
 //! ```no_run
+//! use std::sync::mpsc::channel;
 //! use std::io::timer::Timer;
 //! use std::time::Duration;
 //!
@@ -129,8 +129,8 @@
 //!
 //! loop {
 //!     select! {
-//!         val = rx.recv() => println!("Received {}", val),
-//!         () = timeout.recv() => {
+//!         val = rx.recv() => println!("Received {}", val.unwrap()),
+//!         _ = timeout.recv() => {
 //!             println!("timed out, total time was more than 10 seconds");
 //!             break;
 //!         }
@@ -143,6 +143,7 @@
 //! has been inactive for 5 seconds:
 //!
 //! ```no_run
+//! use std::sync::mpsc::channel;
 //! use std::io::timer::Timer;
 //! use std::time::Duration;
 //!
@@ -153,8 +154,8 @@
 //!     let timeout = timer.oneshot(Duration::seconds(5));
 //!
 //!     select! {
-//!         val = rx.recv() => println!("Received {}", val),
-//!         () = timeout.recv() => {
+//!         val = rx.recv() => println!("Received {}", val.unwrap()),
+//!         _ = timeout.recv() => {
 //!             println!("timed out, no message received in 5 seconds");
 //!             break;
 //!         }
@@ -312,38 +313,19 @@
 // And now that you've seen all the races that I found and attempted to fix,
 // here's the code for you to find some more!
 
-use core::prelude::*;
+use prelude::v1::*;
 
-pub use self::TryRecvError::*;
-pub use self::TrySendError::*;
-
-use alloc::arc::Arc;
-use core::kinds;
-use core::kinds::marker;
-use core::mem;
-use core::cell::UnsafeCell;
+use sync::Arc;
+use fmt;
+use kinds::marker;
+use mem;
+use cell::UnsafeCell;
 
 pub use self::select::{Select, Handle};
 use self::select::StartResult;
 use self::select::StartResult::*;
 use self::blocking::SignalToken;
 
-macro_rules! test {
-    { fn $name:ident() $b:block $(#[$a:meta])*} => (
-        mod $name {
-            #![allow(unused_imports)]
-
-            use super::*;
-            use comm::*;
-            use thread::Thread;
-            use prelude::{Ok, Err, spawn, range, drop, Box, Some, None, Option};
-            use prelude::{Vec, Buffer, from_str, Clone};
-
-            $(#[$a])* #[test] fn f() { $b }
-        }
-    )
-}
-
 mod blocking;
 mod oneshot;
 mod select;
@@ -355,7 +337,7 @@ mod spsc_queue;
 
 /// The receiving-half of Rust's channel type. This half can only be owned by
 /// one task
-#[unstable]
+#[stable]
 pub struct Receiver<T> {
     inner: UnsafeCell<Flavor<T>>,
 }
@@ -367,14 +349,14 @@ unsafe impl<T:Send> Send for Receiver<T> { }
 /// An iterator over messages on a receiver, this iterator will block
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
-#[unstable]
-pub struct Messages<'a, T:'a> {
+#[stable]
+pub struct Iter<'a, T:'a> {
     rx: &'a Receiver<T>
 }
 
 /// The sending-half of Rust's asynchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[unstable]
+#[stable]
 pub struct Sender<T> {
     inner: UnsafeCell<Flavor<T>>,
 }
@@ -385,30 +367,50 @@ unsafe impl<T:Send> Send for Sender<T> { }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[unstable = "this type may be renamed, but it will always exist"]
+#[stable]
 pub struct SyncSender<T> {
     inner: Arc<RacyCell<sync::Packet<T>>>,
     // can't share in an arc
     _marker: marker::NoSync,
 }
 
+/// An error returned from the `send` function on channels.
+///
+/// A `send` operation can only fail if the receiving end of a channel is
+/// disconnected, implying that the data could never be received. The error
+/// contains the data being sent as a payload so it can be recovered.
+#[deriving(PartialEq, Eq)]
+#[stable]
+pub struct SendError<T>(pub T);
+
+/// An error returned from the `recv` function on a `Receiver`.
+///
+/// The `recv` operation can only fail if the sending half of a channel is
+/// disconnected, implying that no further messages will ever be received.
+#[deriving(PartialEq, Eq, Clone, Copy)]
+#[stable]
+pub struct RecvError;
+
 /// This enumeration is the list of the possible reasons that try_recv could not
 /// return data when called.
-#[deriving(PartialEq, Clone, Copy, Show)]
-#[experimental = "this is likely to be removed in changing try_recv()"]
+#[deriving(PartialEq, Clone, Copy)]
+#[stable]
 pub enum TryRecvError {
     /// This channel is currently empty, but the sender(s) have not yet
     /// disconnected, so data may yet become available.
+    #[stable]
     Empty,
+
     /// This channel's sending half has become disconnected, and there will
     /// never be any more data received on this channel
+    #[stable]
     Disconnected,
 }
 
 /// This enumeration is the list of the possible error outcomes for the
 /// `SyncSender::try_send` method.
-#[deriving(PartialEq, Clone, Show)]
-#[experimental = "this is likely to be removed in changing try_send()"]
+#[deriving(PartialEq, Clone)]
+#[stable]
 pub enum TrySendError<T> {
     /// The data could not be sent on the channel because it would require that
     /// the callee block to send the data.
@@ -416,10 +418,13 @@ pub enum TrySendError<T> {
     /// If this is a buffered channel, then the buffer is full at this time. If
     /// this is not a buffered channel, then there is no receiver available to
     /// acquire the data.
+    #[stable]
     Full(T),
+
     /// This channel's receiving half has disconnected, so the data could not be
     /// sent. The data is returned back to the callee in this case.
-    RecvDisconnected(T),
+    #[stable]
+    Disconnected(T),
 }
 
 enum Flavor<T> {
@@ -458,6 +463,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// # Example
 ///
 /// ```
+/// use std::sync::mpsc::channel;
 /// use std::thread::Thread;
 ///
 /// // tx is is the sending half (tx for transmission), and rx is the receiving
@@ -467,15 +473,15 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// // Spawn off an expensive computation
 /// Thread::spawn(move|| {
 /// #   fn expensive_computation() {}
-///     tx.send(expensive_computation());
+///     tx.send(expensive_computation()).unwrap();
 /// }).detach();
 ///
 /// // Do some useful work for awhile
 ///
 /// // Let's see what that answer was
-/// println!("{}", rx.recv());
+/// println!("{}", rx.recv().unwrap());
 /// ```
-#[unstable]
+#[stable]
 pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
     let a = Arc::new(RacyCell::new(oneshot::Packet::new()));
     (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a)))
@@ -499,23 +505,23 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
 /// # Example
 ///
 /// ```
+/// use std::sync::mpsc::sync_channel;
 /// use std::thread::Thread;
 ///
 /// let (tx, rx) = sync_channel(1);
 ///
 /// // this returns immediately
-/// tx.send(1i);
+/// tx.send(1i).unwrap();
 ///
 /// Thread::spawn(move|| {
 ///     // this will block until the previous message has been received
-///     tx.send(2i);
+///     tx.send(2i).unwrap();
 /// }).detach();
 ///
-/// assert_eq!(rx.recv(), 1i);
-/// assert_eq!(rx.recv(), 2i);
+/// assert_eq!(rx.recv().unwrap(), 1i);
+/// assert_eq!(rx.recv().unwrap(), 2i);
 /// ```
-#[unstable = "this function may be renamed to more accurately reflect the type \
-              of channel that is is creating"]
+#[stable]
 pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
     let a = Arc::new(RacyCell::new(sync::Packet::new(bound)));
     (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a)))
@@ -532,33 +538,6 @@ impl<T: Send> Sender<T> {
         }
     }
 
-    /// Sends a value along this channel to be received by the corresponding
-    /// receiver.
-    ///
-    /// Rust channels are infinitely buffered so this method will never block.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if the other end of the channel has hung up.
-    /// This means that if the corresponding receiver has fallen out of scope,
-    /// this function will trigger a panic message saying that a message is
-    /// being sent on a closed channel.
-    ///
-    /// Note that if this function does *not* panic, it does not mean that the
-    /// data will be successfully received. All sends are placed into a queue,
-    /// so it is possible for a send to succeed (the other end is alive), but
-    /// then the other end could immediately disconnect.
-    ///
-    /// The purpose of this functionality is to propagate panics among tasks.
-    /// If a panic is not desired, then consider using the `send_opt` method
-    #[experimental = "this function is being considered candidate for removal \
-                      to adhere to the general guidelines of rust"]
-    pub fn send(&self, t: T) {
-        if self.send_opt(t).is_err() {
-            panic!("sending on a closed channel");
-        }
-    }
-
     /// Attempts to send a value on this channel, returning it back if it could
     /// not be sent.
     ///
@@ -570,37 +549,34 @@ impl<T: Send> Sender<T> {
     /// will be received.  It is possible for the corresponding receiver to
     /// hang up immediately after this function returns `Ok`.
     ///
-    /// Like `send`, this method will never block.
-    ///
-    /// # Panics
-    ///
-    /// This method will never panic, it will return the message back to the
-    /// caller if the other end is disconnected
+    /// This method will never block the current thread.
     ///
     /// # Example
     ///
     /// ```
+    /// use std::sync::mpsc::channel;
+    ///
     /// let (tx, rx) = channel();
     ///
     /// // This send is always successful
-    /// assert_eq!(tx.send_opt(1i), Ok(()));
+    /// tx.send(1i).unwrap();
     ///
     /// // This send will fail because the receiver is gone
     /// drop(rx);
-    /// assert_eq!(tx.send_opt(1i), Err(1));
+    /// assert_eq!(tx.send(1i).err().unwrap().0, 1);
     /// ```
-    #[unstable = "this function may be renamed to send() in the future"]
-    pub fn send_opt(&self, t: T) -> Result<(), T> {
+    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         let (new_inner, ret) = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
                 unsafe {
                     let p = p.get();
                     if !(*p).sent() {
-                        return (*p).send(t);
+                        return (*p).send(t).map_err(SendError);
                     } else {
                         let a =
                             Arc::new(RacyCell::new(stream::Packet::new()));
-                        match (*p).upgrade(Receiver::new(Flavor::Stream(a.clone()))) {
+                        let rx = Receiver::new(Flavor::Stream(a.clone()));
+                        match (*p).upgrade(rx) {
                             oneshot::UpSuccess => {
                                 let ret = (*a.get()).send(t);
                                 (a, ret)
@@ -618,8 +594,12 @@ impl<T: Send> Sender<T> {
                     }
                 }
             }
-            Flavor::Stream(ref p) => return unsafe { (*p.get()).send(t) },
-            Flavor::Shared(ref p) => return unsafe { (*p.get()).send(t) },
+            Flavor::Stream(ref p) => return unsafe {
+                (*p.get()).send(t).map_err(SendError)
+            },
+            Flavor::Shared(ref p) => return unsafe {
+                (*p.get()).send(t).map_err(SendError)
+            },
             Flavor::Sync(..) => unreachable!(),
         };
 
@@ -627,7 +607,7 @@ impl<T: Send> Sender<T> {
             let tmp = Sender::new(Flavor::Stream(new_inner));
             mem::swap(self.inner_mut(), tmp.inner_mut());
         }
-        return ret;
+        ret.map_err(SendError)
     }
 }
 
@@ -639,7 +619,8 @@ impl<T: Send> Clone for Sender<T> {
                 let a = Arc::new(RacyCell::new(shared::Packet::new()));
                 unsafe {
                     let guard = (*a.get()).postinit_lock();
-                    match (*p.get()).upgrade(Receiver::new(Flavor::Shared(a.clone()))) {
+                    let rx = Receiver::new(Flavor::Shared(a.clone()));
+                    match (*p.get()).upgrade(rx) {
                         oneshot::UpSuccess |
                         oneshot::UpDisconnected => (a, None, guard),
                         oneshot::UpWoke(task) => (a, Some(task), guard)
@@ -650,7 +631,8 @@ impl<T: Send> Clone for Sender<T> {
                 let a = Arc::new(RacyCell::new(shared::Packet::new()));
                 unsafe {
                     let guard = (*a.get()).postinit_lock();
-                    match (*p.get()).upgrade(Receiver::new(Flavor::Shared(a.clone()))) {
+                    let rx = Receiver::new(Flavor::Shared(a.clone()));
+                    match (*p.get()).upgrade(rx) {
                         stream::UpSuccess |
                         stream::UpDisconnected => (a, None, guard),
                         stream::UpWoke(task) => (a, Some(task), guard),
@@ -701,59 +683,29 @@ impl<T: Send> SyncSender<T> {
     /// available or a receiver is available to hand off the message to.
     ///
     /// Note that a successful send does *not* guarantee that the receiver will
-    /// ever see the data if there is a buffer on this channel. Messages may be
+    /// ever see the data if there is a buffer on this channel. Items may be
     /// enqueued in the internal buffer for the receiver to receive at a later
     /// time. If the buffer size is 0, however, it can be guaranteed that the
     /// receiver has indeed received the data if this function returns success.
     ///
-    /// # Panics
-    ///
-    /// Similarly to `Sender::send`, this function will panic if the
-    /// corresponding `Receiver` for this channel has disconnected. This
-    /// behavior is used to propagate panics among tasks.
-    ///
-    /// If a panic is not desired, you can achieve the same semantics with the
-    /// `SyncSender::send_opt` method which will not panic if the receiver
-    /// disconnects.
-    #[experimental = "this function is being considered candidate for removal \
-                      to adhere to the general guidelines of rust"]
-    pub fn send(&self, t: T) {
-        if self.send_opt(t).is_err() {
-            panic!("sending on a closed channel");
-        }
-    }
-
-    /// Send a value on a channel, returning it back if the receiver
-    /// disconnected
-    ///
-    /// This method will *block* to send the value `t` on the channel, but if
-    /// the value could not be sent due to the receiver disconnecting, the value
-    /// is returned back to the callee. This function is similar to `try_send`,
-    /// except that it will block if the channel is currently full.
-    ///
-    /// # Panics
-    ///
-    /// This function cannot panic.
-    #[unstable = "this function may be renamed to send() in the future"]
-    pub fn send_opt(&self, t: T) -> Result<(), T> {
-        unsafe { (*self.inner.get()).send(t) }
+    /// This function will never panic, but it may return `Err` if the
+    /// `Receiver` has disconnected and is no longer able to receive
+    /// information.
+    #[stable]
+    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
+        unsafe { (*self.inner.get()).send(t).map_err(SendError) }
     }
 
     /// Attempts to send a value on this channel without blocking.
     ///
-    /// This method differs from `send_opt` by returning immediately if the
+    /// This method differs from `send` by returning immediately if the
     /// channel's buffer is full or no receiver is waiting to acquire some
-    /// data. Compared with `send_opt`, this function has two failure cases
+    /// data. Compared with `send`, this function has two failure cases
     /// instead of one (one for disconnection, one for a full buffer).
     ///
     /// See `SyncSender::send` for notes about guarantees of whether the
     /// receiver has received the data or not if this function is successful.
-    ///
-    /// # Panics
-    ///
-    /// This function cannot panic
-    #[unstable = "the return type of this function is candidate for \
-                  modification"]
+    #[stable]
     pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
         unsafe { (*self.inner.get()).try_send(t) }
     }
@@ -783,34 +735,6 @@ impl<T: Send> Receiver<T> {
         Receiver { inner: UnsafeCell::new(inner) }
     }
 
-    /// Blocks waiting for a value on this receiver
-    ///
-    /// This function will block if necessary to wait for a corresponding send
-    /// on the channel from its paired `Sender` structure. This receiver will
-    /// be woken up when data is ready, and the data will be returned.
-    ///
-    /// # Panics
-    ///
-    /// Similar to channels, this method will trigger a task panic if the
-    /// other end of the channel has hung up (been deallocated). The purpose of
-    /// this is to propagate panics among tasks.
-    ///
-    /// If a panic is not desired, then there are two options:
-    ///
-    /// * If blocking is still desired, the `recv_opt` method will return `None`
-    ///   when the other end hangs up
-    ///
-    /// * If blocking is not desired, then the `try_recv` method will attempt to
-    ///   peek at a value on this receiver.
-    #[experimental = "this function is being considered candidate for removal \
-                      to adhere to the general guidelines of rust"]
-    pub fn recv(&self) -> T {
-        match self.recv_opt() {
-            Ok(t) => t,
-            Err(()) => panic!("receiving on a closed channel"),
-        }
-    }
-
     /// Attempts to return a pending value on this receiver without blocking
     ///
     /// This method will never block the caller in order to wait for data to
@@ -819,42 +743,46 @@ impl<T: Send> Receiver<T> {
     ///
     /// This is useful for a flavor of "optimistic check" before deciding to
     /// block on a receiver.
-    ///
-    /// # Panics
-    ///
-    /// This function cannot panic.
-    #[unstable = "the return type of this function may be altered"]
+    #[stable]
     pub fn try_recv(&self) -> Result<T, TryRecvError> {
         loop {
             let new_port = match *unsafe { self.inner() } {
                 Flavor::Oneshot(ref p) => {
                     match unsafe { (*p.get()).try_recv() } {
                         Ok(t) => return Ok(t),
-                        Err(oneshot::Empty) => return Err(Empty),
-                        Err(oneshot::Disconnected) => return Err(Disconnected),
+                        Err(oneshot::Empty) => return Err(TryRecvError::Empty),
+                        Err(oneshot::Disconnected) => {
+                            return Err(TryRecvError::Disconnected)
+                        }
                         Err(oneshot::Upgraded(rx)) => rx,
                     }
                 }
                 Flavor::Stream(ref p) => {
                     match unsafe { (*p.get()).try_recv() } {
                         Ok(t) => return Ok(t),
-                        Err(stream::Empty) => return Err(Empty),
-                        Err(stream::Disconnected) => return Err(Disconnected),
+                        Err(stream::Empty) => return Err(TryRecvError::Empty),
+                        Err(stream::Disconnected) => {
+                            return Err(TryRecvError::Disconnected)
+                        }
                         Err(stream::Upgraded(rx)) => rx,
                     }
                 }
                 Flavor::Shared(ref p) => {
                     match unsafe { (*p.get()).try_recv() } {
                         Ok(t) => return Ok(t),
-                        Err(shared::Empty) => return Err(Empty),
-                        Err(shared::Disconnected) => return Err(Disconnected),
+                        Err(shared::Empty) => return Err(TryRecvError::Empty),
+                        Err(shared::Disconnected) => {
+                            return Err(TryRecvError::Disconnected)
+                        }
                     }
                 }
                 Flavor::Sync(ref p) => {
                     match unsafe { (*p.get()).try_recv() } {
                         Ok(t) => return Ok(t),
-                        Err(sync::Empty) => return Err(Empty),
-                        Err(sync::Disconnected) => return Err(Disconnected),
+                        Err(sync::Empty) => return Err(TryRecvError::Empty),
+                        Err(sync::Disconnected) => {
+                            return Err(TryRecvError::Disconnected)
+                        }
                     }
                 }
             };
@@ -865,27 +793,26 @@ impl<T: Send> Receiver<T> {
         }
     }
 
-    /// Attempt to wait for a value on this receiver, but does not panic if the
+    /// Attempt to wait for a value on this receiver, returning an error if the
     /// corresponding channel has hung up.
     ///
-    /// This implementation of iterators for ports will always block if there is
-    /// not data available on the receiver, but it will not panic in the case
-    /// that the channel has been deallocated.
+    /// This function will always block the current thread if there is no data
+    /// available and it's possible for more data to be sent. Once a message is
+    /// sent to the corresponding `Sender`, then this receiver will wake up and
+    /// return that message.
     ///
-    /// In other words, this function has the same semantics as the `recv`
-    /// method except for the panic aspect.
-    ///
-    /// If the channel has hung up, then `Err` is returned. Otherwise `Ok` of
-    /// the value found on the receiver is returned.
-    #[unstable = "this function may be renamed to recv()"]
-    pub fn recv_opt(&self) -> Result<T, ()> {
+    /// If the corresponding `Sender` has disconnected, or it disconnects while
+    /// this call is blocking, this call will wake up and return `Err` to
+    /// indicate that no more messages can ever be received on this channel.
+    #[stable]
+    pub fn recv(&self) -> Result<T, RecvError> {
         loop {
             let new_port = match *unsafe { self.inner() } {
                 Flavor::Oneshot(ref p) => {
                     match unsafe { (*p.get()).recv() } {
                         Ok(t) => return Ok(t),
                         Err(oneshot::Empty) => return unreachable!(),
-                        Err(oneshot::Disconnected) => return Err(()),
+                        Err(oneshot::Disconnected) => return Err(RecvError),
                         Err(oneshot::Upgraded(rx)) => rx,
                     }
                 }
@@ -893,7 +820,7 @@ impl<T: Send> Receiver<T> {
                     match unsafe { (*p.get()).recv() } {
                         Ok(t) => return Ok(t),
                         Err(stream::Empty) => return unreachable!(),
-                        Err(stream::Disconnected) => return Err(()),
+                        Err(stream::Disconnected) => return Err(RecvError),
                         Err(stream::Upgraded(rx)) => rx,
                     }
                 }
@@ -901,10 +828,12 @@ impl<T: Send> Receiver<T> {
                     match unsafe { (*p.get()).recv() } {
                         Ok(t) => return Ok(t),
                         Err(shared::Empty) => return unreachable!(),
-                        Err(shared::Disconnected) => return Err(()),
+                        Err(shared::Disconnected) => return Err(RecvError),
                     }
                 }
-                Flavor::Sync(ref p) => return unsafe { (*p.get()).recv() }
+                Flavor::Sync(ref p) => return unsafe {
+                    (*p.get()).recv().map_err(|()| RecvError)
+                }
             };
             unsafe {
                 mem::swap(self.inner_mut(), new_port.inner_mut());
@@ -914,9 +843,9 @@ impl<T: Send> Receiver<T> {
 
     /// Returns an iterator that will block waiting for messages, but never
     /// `panic!`. It will return `None` when the channel has hung up.
-    #[unstable]
-    pub fn iter<'a>(&'a self) -> Messages<'a, T> {
-        Messages { rx: self }
+    #[stable]
+    pub fn iter(&self) -> Iter<T> {
+        Iter { rx: self }
     }
 }
 
@@ -1007,8 +936,8 @@ impl<T: Send> select::Packet for Receiver<T> {
 }
 
 #[unstable]
-impl<'a, T: Send> Iterator<T> for Messages<'a, T> {
-    fn next(&mut self) -> Option<T> { self.rx.recv_opt().ok() }
+impl<'a, T: Send> Iterator<T> for Iter<'a, T> {
+    fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
 }
 
 #[unsafe_destructor]
@@ -1041,368 +970,425 @@ impl<T> RacyCell<T> {
 
 unsafe impl<T:Send> Send for RacyCell<T> { }
 
-unsafe impl<T> kinds::Sync for RacyCell<T> { } // Oh dear
+unsafe impl<T> Sync for RacyCell<T> { } // Oh dear
+
+impl<T> fmt::Show for SendError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "sending on a closed channel".fmt(f)
+    }
+}
+
+impl<T> fmt::Show for TrySendError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            TrySendError::Full(..) => {
+                "sending on a full channel".fmt(f)
+            }
+            TrySendError::Disconnected(..) => {
+                "sending on a closed channel".fmt(f)
+            }
+        }
+    }
+}
+
+impl fmt::Show for RecvError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "receiving on a closed channel".fmt(f)
+    }
+}
 
+impl fmt::Show for TryRecvError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            TryRecvError::Empty => {
+                "receiving on an empty channel".fmt(f)
+            }
+            TryRecvError::Disconnected => {
+                "receiving on a closed channel".fmt(f)
+            }
+        }
+    }
+}
 
 #[cfg(test)]
 mod test {
-    use super::*;
-    use prelude::{spawn, range, Some, None, from_str, Clone, Str};
+    use prelude::v1::*;
+
     use os;
+    use super::*;
+    use thread::Thread;
 
     pub fn stress_factor() -> uint {
         match os::getenv("RUST_TEST_STRESS") {
-            Some(val) => from_str::<uint>(val.as_slice()).unwrap(),
+            Some(val) => val.parse().unwrap(),
             None => 1,
         }
     }
 
-    test! { fn smoke() {
+    #[test]
+    fn smoke() {
         let (tx, rx) = channel::<int>();
-        tx.send(1);
-        assert_eq!(rx.recv(), 1);
-    } }
+        tx.send(1).unwrap();
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
 
-    test! { fn drop_full() {
+    #[test]
+    fn drop_full() {
         let (tx, _rx) = channel();
-        tx.send(box 1i);
-    } }
+        tx.send(box 1i).unwrap();
+    }
 
-    test! { fn drop_full_shared() {
+    #[test]
+    fn drop_full_shared() {
         let (tx, _rx) = channel();
         drop(tx.clone());
         drop(tx.clone());
-        tx.send(box 1i);
-    } }
+        tx.send(box 1i).unwrap();
+    }
 
-    test! { fn smoke_shared() {
+    #[test]
+    fn smoke_shared() {
         let (tx, rx) = channel::<int>();
-        tx.send(1);
-        assert_eq!(rx.recv(), 1);
+        tx.send(1).unwrap();
+        assert_eq!(rx.recv().unwrap(), 1);
         let tx = tx.clone();
-        tx.send(1);
-        assert_eq!(rx.recv(), 1);
-    } }
+        tx.send(1).unwrap();
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
 
-    test! { fn smoke_threads() {
+    #[test]
+    fn smoke_threads() {
         let (tx, rx) = channel::<int>();
-        spawn(move|| {
-            tx.send(1);
+        let _t = Thread::spawn(move|| {
+            tx.send(1).unwrap();
         });
-        assert_eq!(rx.recv(), 1);
-    } }
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
 
-    test! { fn smoke_port_gone() {
+    #[test]
+    fn smoke_port_gone() {
         let (tx, rx) = channel::<int>();
         drop(rx);
-        tx.send(1);
-    } #[should_fail] }
+        assert!(tx.send(1).is_err());
+    }
 
-    test! { fn smoke_shared_port_gone() {
+    #[test]
+    fn smoke_shared_port_gone() {
         let (tx, rx) = channel::<int>();
         drop(rx);
-        tx.send(1);
-    } #[should_fail] }
+        assert!(tx.send(1).is_err())
+    }
 
-    test! { fn smoke_shared_port_gone2() {
+    #[test]
+    fn smoke_shared_port_gone2() {
         let (tx, rx) = channel::<int>();
         drop(rx);
         let tx2 = tx.clone();
         drop(tx);
-        tx2.send(1);
-    } #[should_fail] }
+        assert!(tx2.send(1).is_err());
+    }
 
-    test! { fn port_gone_concurrent() {
+    #[test]
+    fn port_gone_concurrent() {
         let (tx, rx) = channel::<int>();
-        spawn(move|| {
-            rx.recv();
+        let _t = Thread::spawn(move|| {
+            rx.recv().unwrap();
         });
-        loop { tx.send(1) }
-    } #[should_fail] }
+        while tx.send(1).is_ok() {}
+    }
 
-    test! { fn port_gone_concurrent_shared() {
+    #[test]
+    fn port_gone_concurrent_shared() {
         let (tx, rx) = channel::<int>();
         let tx2 = tx.clone();
-        spawn(move|| {
-            rx.recv();
+        let _t = Thread::spawn(move|| {
+            rx.recv().unwrap();
         });
-        loop {
-            tx.send(1);
-            tx2.send(1);
-        }
-    } #[should_fail] }
+        while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
+    }
 
-    test! { fn smoke_chan_gone() {
+    #[test]
+    fn smoke_chan_gone() {
         let (tx, rx) = channel::<int>();
         drop(tx);
-        rx.recv();
-    } #[should_fail] }
+        assert!(rx.recv().is_err());
+    }
 
-    test! { fn smoke_chan_gone_shared() {
+    #[test]
+    fn smoke_chan_gone_shared() {
         let (tx, rx) = channel::<()>();
         let tx2 = tx.clone();
         drop(tx);
         drop(tx2);
-        rx.recv();
-    } #[should_fail] }
+        assert!(rx.recv().is_err());
+    }
 
-    test! { fn chan_gone_concurrent() {
+    #[test]
+    fn chan_gone_concurrent() {
         let (tx, rx) = channel::<int>();
-        spawn(move|| {
-            tx.send(1);
-            tx.send(1);
+        let _t = Thread::spawn(move|| {
+            tx.send(1).unwrap();
+            tx.send(1).unwrap();
         });
-        loop { rx.recv(); }
-    } #[should_fail] }
+        while rx.recv().is_ok() {}
+    }
 
-    test! { fn stress() {
+    #[test]
+    fn stress() {
         let (tx, rx) = channel::<int>();
-        spawn(move|| {
-            for _ in range(0u, 10000) { tx.send(1i); }
+        let t = Thread::spawn(move|| {
+            for _ in range(0u, 10000) { tx.send(1i).unwrap(); }
         });
         for _ in range(0u, 10000) {
-            assert_eq!(rx.recv(), 1);
+            assert_eq!(rx.recv().unwrap(), 1);
         }
-    } }
+        t.join().ok().unwrap();
+    }
 
-    test! { fn stress_shared() {
+    #[test]
+    fn stress_shared() {
         static AMT: uint = 10000;
         static NTHREADS: uint = 8;
         let (tx, rx) = channel::<int>();
-        let (dtx, drx) = channel::<()>();
 
-        spawn(move|| {
+        let t = Thread::spawn(move|| {
             for _ in range(0, AMT * NTHREADS) {
-                assert_eq!(rx.recv(), 1);
+                assert_eq!(rx.recv().unwrap(), 1);
             }
             match rx.try_recv() {
                 Ok(..) => panic!(),
                 _ => {}
             }
-            dtx.send(());
         });
 
         for _ in range(0, NTHREADS) {
             let tx = tx.clone();
-            spawn(move|| {
-                for _ in range(0, AMT) { tx.send(1); }
-            });
+            Thread::spawn(move|| {
+                for _ in range(0, AMT) { tx.send(1).unwrap(); }
+            }).detach();
         }
         drop(tx);
-        drx.recv();
-    } }
+        t.join().ok().unwrap();
+    }
 
     #[test]
     fn send_from_outside_runtime() {
         let (tx1, rx1) = channel::<()>();
         let (tx2, rx2) = channel::<int>();
-        let (tx3, rx3) = channel::<()>();
-        let tx4 = tx3.clone();
-        spawn(move|| {
-            tx1.send(());
+        let t1 = Thread::spawn(move|| {
+            tx1.send(()).unwrap();
             for _ in range(0i, 40) {
-                assert_eq!(rx2.recv(), 1);
+                assert_eq!(rx2.recv().unwrap(), 1);
             }
-            tx3.send(());
         });
-        rx1.recv();
-        spawn(move|| {
+        rx1.recv().unwrap();
+        let t2 = Thread::spawn(move|| {
             for _ in range(0i, 40) {
-                tx2.send(1);
+                tx2.send(1).unwrap();
             }
-            tx4.send(());
         });
-        rx3.recv();
-        rx3.recv();
+        t1.join().ok().unwrap();
+        t2.join().ok().unwrap();
     }
 
     #[test]
     fn recv_from_outside_runtime() {
         let (tx, rx) = channel::<int>();
-        let (dtx, drx) = channel();
-        spawn(move|| {
+        let t = Thread::spawn(move|| {
             for _ in range(0i, 40) {
-                assert_eq!(rx.recv(), 1);
+                assert_eq!(rx.recv().unwrap(), 1);
             }
-            dtx.send(());
         });
         for _ in range(0u, 40) {
-            tx.send(1);
+            tx.send(1).unwrap();
         }
-        drx.recv();
+        t.join().ok().unwrap();
     }
 
     #[test]
     fn no_runtime() {
         let (tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<int>();
-        let (tx3, rx3) = channel::<()>();
-        let tx4 = tx3.clone();
-        spawn(move|| {
-            assert_eq!(rx1.recv(), 1);
-            tx2.send(2);
-            tx4.send(());
+        let t1 = Thread::spawn(move|| {
+            assert_eq!(rx1.recv().unwrap(), 1);
+            tx2.send(2).unwrap();
         });
-        spawn(move|| {
-            tx1.send(1);
-            assert_eq!(rx2.recv(), 2);
-            tx3.send(());
+        let t2 = Thread::spawn(move|| {
+            tx1.send(1).unwrap();
+            assert_eq!(rx2.recv().unwrap(), 2);
         });
-        rx3.recv();
-        rx3.recv();
+        t1.join().ok().unwrap();
+        t2.join().ok().unwrap();
     }
 
-    test! { fn oneshot_single_thread_close_port_first() {
+    #[test]
+    fn oneshot_single_thread_close_port_first() {
         // Simple test of closing without sending
         let (_tx, rx) = channel::<int>();
         drop(rx);
-    } }
+    }
 
-    test! { fn oneshot_single_thread_close_chan_first() {
+    #[test]
+    fn oneshot_single_thread_close_chan_first() {
         // Simple test of closing without sending
         let (tx, _rx) = channel::<int>();
         drop(tx);
-    } }
+    }
 
-    test! { fn oneshot_single_thread_send_port_close() {
+    #[test]
+    fn oneshot_single_thread_send_port_close() {
         // Testing that the sender cleans up the payload if receiver is closed
         let (tx, rx) = channel::<Box<int>>();
         drop(rx);
-        tx.send(box 0);
-    } #[should_fail] }
+        assert!(tx.send(box 0).is_err());
+    }
 
-    test! { fn oneshot_single_thread_recv_chan_close() {
+    #[test]
+    fn oneshot_single_thread_recv_chan_close() {
         // Receiving on a closed chan will panic
         let res = Thread::spawn(move|| {
             let (tx, rx) = channel::<int>();
             drop(tx);
-            rx.recv();
+            rx.recv().unwrap();
         }).join();
         // What is our res?
         assert!(res.is_err());
-    } }
+    }
 
-    test! { fn oneshot_single_thread_send_then_recv() {
+    #[test]
+    fn oneshot_single_thread_send_then_recv() {
         let (tx, rx) = channel::<Box<int>>();
-        tx.send(box 10);
-        assert!(rx.recv() == box 10);
-    } }
+        tx.send(box 10).unwrap();
+        assert!(rx.recv().unwrap() == box 10);
+    }
 
-    test! { fn oneshot_single_thread_try_send_open() {
+    #[test]
+    fn oneshot_single_thread_try_send_open() {
         let (tx, rx) = channel::<int>();
-        assert!(tx.send_opt(10).is_ok());
-        assert!(rx.recv() == 10);
-    } }
+        assert!(tx.send(10).is_ok());
+        assert!(rx.recv().unwrap() == 10);
+    }
 
-    test! { fn oneshot_single_thread_try_send_closed() {
+    #[test]
+    fn oneshot_single_thread_try_send_closed() {
         let (tx, rx) = channel::<int>();
         drop(rx);
-        assert!(tx.send_opt(10).is_err());
-    } }
+        assert!(tx.send(10).is_err());
+    }
 
-    test! { fn oneshot_single_thread_try_recv_open() {
+    #[test]
+    fn oneshot_single_thread_try_recv_open() {
         let (tx, rx) = channel::<int>();
-        tx.send(10);
-        assert!(rx.recv_opt() == Ok(10));
-    } }
+        tx.send(10).unwrap();
+        assert!(rx.recv() == Ok(10));
+    }
 
-    test! { fn oneshot_single_thread_try_recv_closed() {
+    #[test]
+    fn oneshot_single_thread_try_recv_closed() {
         let (tx, rx) = channel::<int>();
         drop(tx);
-        assert!(rx.recv_opt() == Err(()));
-    } }
+        assert!(rx.recv().is_err());
+    }
 
-    test! { fn oneshot_single_thread_peek_data() {
+    #[test]
+    fn oneshot_single_thread_peek_data() {
         let (tx, rx) = channel::<int>();
-        assert_eq!(rx.try_recv(), Err(Empty));
-        tx.send(10);
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+        tx.send(10).unwrap();
         assert_eq!(rx.try_recv(), Ok(10));
-    } }
+    }
 
-    test! { fn oneshot_single_thread_peek_close() {
+    #[test]
+    fn oneshot_single_thread_peek_close() {
         let (tx, rx) = channel::<int>();
         drop(tx);
-        assert_eq!(rx.try_recv(), Err(Disconnected));
-        assert_eq!(rx.try_recv(), Err(Disconnected));
-    } }
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+    }
 
-    test! { fn oneshot_single_thread_peek_open() {
+    #[test]
+    fn oneshot_single_thread_peek_open() {
         let (_tx, rx) = channel::<int>();
-        assert_eq!(rx.try_recv(), Err(Empty));
-    } }
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+    }
 
-    test! { fn oneshot_multi_task_recv_then_send() {
+    #[test]
+    fn oneshot_multi_task_recv_then_send() {
         let (tx, rx) = channel::<Box<int>>();
-        spawn(move|| {
-            assert!(rx.recv() == box 10);
+        let _t = Thread::spawn(move|| {
+            assert!(rx.recv().unwrap() == box 10);
         });
 
-        tx.send(box 10);
-    } }
+        tx.send(box 10).unwrap();
+    }
 
-    test! { fn oneshot_multi_task_recv_then_close() {
+    #[test]
+    fn oneshot_multi_task_recv_then_close() {
         let (tx, rx) = channel::<Box<int>>();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             drop(tx);
         });
         let res = Thread::spawn(move|| {
-            assert!(rx.recv() == box 10);
+            assert!(rx.recv().unwrap() == box 10);
         }).join();
         assert!(res.is_err());
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_close_stress() {
+    #[test]
+    fn oneshot_multi_thread_close_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = channel::<int>();
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 drop(rx);
             });
             drop(tx);
         }
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_send_close_stress() {
+    #[test]
+    fn oneshot_multi_thread_send_close_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = channel::<int>();
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 drop(rx);
             });
             let _ = Thread::spawn(move|| {
-                tx.send(1);
+                tx.send(1).unwrap();
             }).join();
         }
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_recv_close_stress() {
+    #[test]
+    fn oneshot_multi_thread_recv_close_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = channel::<int>();
-            spawn(move|| {
+            Thread::spawn(move|| {
                 let res = Thread::spawn(move|| {
-                    rx.recv();
+                    rx.recv().unwrap();
                 }).join();
                 assert!(res.is_err());
-            });
-            spawn(move|| {
-                spawn(move|| {
+            }).detach();
+            let _t = Thread::spawn(move|| {
+                Thread::spawn(move|| {
                     drop(tx);
-                });
+                }).detach();
             });
         }
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_send_recv_stress() {
+    #[test]
+    fn oneshot_multi_thread_send_recv_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = channel();
-            spawn(move|| {
-                tx.send(box 10i);
-            });
-            spawn(move|| {
-                assert!(rx.recv() == box 10i);
+            let _t = Thread::spawn(move|| {
+                tx.send(box 10i).unwrap();
             });
+            assert!(rx.recv().unwrap() == box 10i);
         }
-    } }
+    }
 
-    test! { fn stream_send_recv_stress() {
+    #[test]
+    fn stream_send_recv_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = channel();
 
@@ -1412,69 +1398,73 @@ mod test {
             fn send(tx: Sender<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                spawn(move|| {
-                    tx.send(box i);
+                Thread::spawn(move|| {
+                    tx.send(box i).unwrap();
                     send(tx, i + 1);
-                });
+                }).detach();
             }
 
             fn recv(rx: Receiver<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                spawn(move|| {
-                    assert!(rx.recv() == box i);
+                Thread::spawn(move|| {
+                    assert!(rx.recv().unwrap() == box i);
                     recv(rx, i + 1);
-                });
+                }).detach();
             }
         }
-    } }
+    }
 
-    test! { fn recv_a_lot() {
+    #[test]
+    fn recv_a_lot() {
         // Regression test that we don't run out of stack in scheduler context
         let (tx, rx) = channel();
-        for _ in range(0i, 10000) { tx.send(()); }
-        for _ in range(0i, 10000) { rx.recv(); }
-    } }
+        for _ in range(0i, 10000) { tx.send(()).unwrap(); }
+        for _ in range(0i, 10000) { rx.recv().unwrap(); }
+    }
 
-    test! { fn shared_chan_stress() {
+    #[test]
+    fn shared_chan_stress() {
         let (tx, rx) = channel();
         let total = stress_factor() + 100;
         for _ in range(0, total) {
             let tx = tx.clone();
-            spawn(move|| {
-                tx.send(());
-            });
+            Thread::spawn(move|| {
+                tx.send(()).unwrap();
+            }).detach();
         }
 
         for _ in range(0, total) {
-            rx.recv();
+            rx.recv().unwrap();
         }
-    } }
+    }
 
-    test! { fn test_nested_recv_iter() {
+    #[test]
+    fn test_nested_recv_iter() {
         let (tx, rx) = channel::<int>();
         let (total_tx, total_rx) = channel::<int>();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut acc = 0;
             for x in rx.iter() {
                 acc += x;
             }
-            total_tx.send(acc);
+            total_tx.send(acc).unwrap();
         });
 
-        tx.send(3);
-        tx.send(1);
-        tx.send(2);
+        tx.send(3).unwrap();
+        tx.send(1).unwrap();
+        tx.send(2).unwrap();
         drop(tx);
-        assert_eq!(total_rx.recv(), 6);
-    } }
+        assert_eq!(total_rx.recv().unwrap(), 6);
+    }
 
-    test! { fn test_recv_iter_break() {
+    #[test]
+    fn test_recv_iter_break() {
         let (tx, rx) = channel::<int>();
         let (count_tx, count_rx) = channel();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut count = 0;
             for x in rx.iter() {
                 if count >= 3 {
@@ -1483,49 +1473,51 @@ mod test {
                     count += x;
                 }
             }
-            count_tx.send(count);
+            count_tx.send(count).unwrap();
         });
 
-        tx.send(2);
-        tx.send(2);
-        tx.send(2);
-        let _ = tx.send_opt(2);
+        tx.send(2).unwrap();
+        tx.send(2).unwrap();
+        tx.send(2).unwrap();
+        let _ = tx.send(2);
         drop(tx);
-        assert_eq!(count_rx.recv(), 4);
-    } }
+        assert_eq!(count_rx.recv().unwrap(), 4);
+    }
 
-    test! { fn try_recv_states() {
+    #[test]
+    fn try_recv_states() {
         let (tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<()>();
         let (tx3, rx3) = channel::<()>();
-        spawn(move|| {
-            rx2.recv();
-            tx1.send(1);
-            tx3.send(());
-            rx2.recv();
+        let _t = Thread::spawn(move|| {
+            rx2.recv().unwrap();
+            tx1.send(1).unwrap();
+            tx3.send(()).unwrap();
+            rx2.recv().unwrap();
             drop(tx1);
-            tx3.send(());
+            tx3.send(()).unwrap();
         });
 
-        assert_eq!(rx1.try_recv(), Err(Empty));
-        tx2.send(());
-        rx3.recv();
+        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+        tx2.send(()).unwrap();
+        rx3.recv().unwrap();
         assert_eq!(rx1.try_recv(), Ok(1));
-        assert_eq!(rx1.try_recv(), Err(Empty));
-        tx2.send(());
-        rx3.recv();
-        assert_eq!(rx1.try_recv(), Err(Disconnected));
-    } }
+        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+        tx2.send(()).unwrap();
+        rx3.recv().unwrap();
+        assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
+    }
 
     // This bug used to end up in a livelock inside of the Receiver destructor
     // because the internal state of the Shared packet was corrupted
-    test! { fn destroy_upgraded_shared_port_when_sender_still_active() {
+    #[test]
+    fn destroy_upgraded_shared_port_when_sender_still_active() {
         let (tx, rx) = channel();
         let (tx2, rx2) = channel();
-        spawn(move|| {
-            rx.recv(); // wait on a oneshot
+        let _t = Thread::spawn(move|| {
+            rx.recv().unwrap(); // wait on a oneshot
             drop(rx);  // destroy a shared
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
         // make sure the other task has gone to sleep
         for _ in range(0u, 5000) { Thread::yield_now(); }
@@ -1533,303 +1525,334 @@ mod test {
         // upgrade to a shared chan and send a message
         let t = tx.clone();
         drop(tx);
-        t.send(());
+        t.send(()).unwrap();
 
         // wait for the child task to exit before we exit
-        rx2.recv();
-    }}
+        rx2.recv().unwrap();
+    }
 }
 
 #[cfg(test)]
 mod sync_tests {
-    use prelude::*;
+    use prelude::v1::*;
+
     use os;
+    use thread::Thread;
+    use super::*;
 
     pub fn stress_factor() -> uint {
         match os::getenv("RUST_TEST_STRESS") {
-            Some(val) => from_str::<uint>(val.as_slice()).unwrap(),
+            Some(val) => val.parse().unwrap(),
             None => 1,
         }
     }
 
-    test! { fn smoke() {
+    #[test]
+    fn smoke() {
         let (tx, rx) = sync_channel::<int>(1);
-        tx.send(1);
-        assert_eq!(rx.recv(), 1);
-    } }
+        tx.send(1).unwrap();
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
 
-    test! { fn drop_full() {
+    #[test]
+    fn drop_full() {
         let (tx, _rx) = sync_channel(1);
-        tx.send(box 1i);
-    } }
+        tx.send(box 1i).unwrap();
+    }
 
-    test! { fn smoke_shared() {
+    #[test]
+    fn smoke_shared() {
         let (tx, rx) = sync_channel::<int>(1);
-        tx.send(1);
-        assert_eq!(rx.recv(), 1);
+        tx.send(1).unwrap();
+        assert_eq!(rx.recv().unwrap(), 1);
         let tx = tx.clone();
-        tx.send(1);
-        assert_eq!(rx.recv(), 1);
-    } }
+        tx.send(1).unwrap();
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
 
-    test! { fn smoke_threads() {
+    #[test]
+    fn smoke_threads() {
         let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| {
-            tx.send(1);
+        let _t = Thread::spawn(move|| {
+            tx.send(1).unwrap();
         });
-        assert_eq!(rx.recv(), 1);
-    } }
+        assert_eq!(rx.recv().unwrap(), 1);
+    }
 
-    test! { fn smoke_port_gone() {
+    #[test]
+    fn smoke_port_gone() {
         let (tx, rx) = sync_channel::<int>(0);
         drop(rx);
-        tx.send(1);
-    } #[should_fail] }
+        assert!(tx.send(1).is_err());
+    }
 
-    test! { fn smoke_shared_port_gone2() {
+    #[test]
+    fn smoke_shared_port_gone2() {
         let (tx, rx) = sync_channel::<int>(0);
         drop(rx);
         let tx2 = tx.clone();
         drop(tx);
-        tx2.send(1);
-    } #[should_fail] }
+        assert!(tx2.send(1).is_err());
+    }
 
-    test! { fn port_gone_concurrent() {
+    #[test]
+    fn port_gone_concurrent() {
         let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| {
-            rx.recv();
+        let _t = Thread::spawn(move|| {
+            rx.recv().unwrap();
         });
-        loop { tx.send(1) }
-    } #[should_fail] }
+        while tx.send(1).is_ok() {}
+    }
 
-    test! { fn port_gone_concurrent_shared() {
+    #[test]
+    fn port_gone_concurrent_shared() {
         let (tx, rx) = sync_channel::<int>(0);
         let tx2 = tx.clone();
-        spawn(move|| {
-            rx.recv();
+        let _t = Thread::spawn(move|| {
+            rx.recv().unwrap();
         });
-        loop {
-            tx.send(1);
-            tx2.send(1);
-        }
-    } #[should_fail] }
+        while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
+    }
 
-    test! { fn smoke_chan_gone() {
+    #[test]
+    fn smoke_chan_gone() {
         let (tx, rx) = sync_channel::<int>(0);
         drop(tx);
-        rx.recv();
-    } #[should_fail] }
+        assert!(rx.recv().is_err());
+    }
 
-    test! { fn smoke_chan_gone_shared() {
+    #[test]
+    fn smoke_chan_gone_shared() {
         let (tx, rx) = sync_channel::<()>(0);
         let tx2 = tx.clone();
         drop(tx);
         drop(tx2);
-        rx.recv();
-    } #[should_fail] }
+        assert!(rx.recv().is_err());
+    }
 
-    test! { fn chan_gone_concurrent() {
+    #[test]
+    fn chan_gone_concurrent() {
         let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| {
-            tx.send(1);
-            tx.send(1);
-        });
-        loop { rx.recv(); }
-    } #[should_fail] }
+        Thread::spawn(move|| {
+            tx.send(1).unwrap();
+            tx.send(1).unwrap();
+        }).detach();
+        while rx.recv().is_ok() {}
+    }
 
-    test! { fn stress() {
+    #[test]
+    fn stress() {
         let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| {
-            for _ in range(0u, 10000) { tx.send(1); }
-        });
+        Thread::spawn(move|| {
+            for _ in range(0u, 10000) { tx.send(1).unwrap(); }
+        }).detach();
         for _ in range(0u, 10000) {
-            assert_eq!(rx.recv(), 1);
+            assert_eq!(rx.recv().unwrap(), 1);
         }
-    } }
+    }
 
-    test! { fn stress_shared() {
+    #[test]
+    fn stress_shared() {
         static AMT: uint = 1000;
         static NTHREADS: uint = 8;
         let (tx, rx) = sync_channel::<int>(0);
         let (dtx, drx) = sync_channel::<()>(0);
 
-        spawn(move|| {
+        Thread::spawn(move|| {
             for _ in range(0, AMT * NTHREADS) {
-                assert_eq!(rx.recv(), 1);
+                assert_eq!(rx.recv().unwrap(), 1);
             }
             match rx.try_recv() {
                 Ok(..) => panic!(),
                 _ => {}
             }
-            dtx.send(());
-        });
+            dtx.send(()).unwrap();
+        }).detach();
 
         for _ in range(0, NTHREADS) {
             let tx = tx.clone();
-            spawn(move|| {
-                for _ in range(0, AMT) { tx.send(1); }
-            });
+            Thread::spawn(move|| {
+                for _ in range(0, AMT) { tx.send(1).unwrap(); }
+            }).detach();
         }
         drop(tx);
-        drx.recv();
-    } }
+        drx.recv().unwrap();
+    }
 
-    test! { fn oneshot_single_thread_close_port_first() {
+    #[test]
+    fn oneshot_single_thread_close_port_first() {
         // Simple test of closing without sending
         let (_tx, rx) = sync_channel::<int>(0);
         drop(rx);
-    } }
+    }
 
-    test! { fn oneshot_single_thread_close_chan_first() {
+    #[test]
+    fn oneshot_single_thread_close_chan_first() {
         // Simple test of closing without sending
         let (tx, _rx) = sync_channel::<int>(0);
         drop(tx);
-    } }
+    }
 
-    test! { fn oneshot_single_thread_send_port_close() {
+    #[test]
+    fn oneshot_single_thread_send_port_close() {
         // Testing that the sender cleans up the payload if receiver is closed
         let (tx, rx) = sync_channel::<Box<int>>(0);
         drop(rx);
-        tx.send(box 0);
-    } #[should_fail] }
+        assert!(tx.send(box 0).is_err());
+    }
 
-    test! { fn oneshot_single_thread_recv_chan_close() {
+    #[test]
+    fn oneshot_single_thread_recv_chan_close() {
         // Receiving on a closed chan will panic
         let res = Thread::spawn(move|| {
             let (tx, rx) = sync_channel::<int>(0);
             drop(tx);
-            rx.recv();
+            rx.recv().unwrap();
         }).join();
         // What is our res?
         assert!(res.is_err());
-    } }
+    }
 
-    test! { fn oneshot_single_thread_send_then_recv() {
+    #[test]
+    fn oneshot_single_thread_send_then_recv() {
         let (tx, rx) = sync_channel::<Box<int>>(1);
-        tx.send(box 10);
-        assert!(rx.recv() == box 10);
-    } }
+        tx.send(box 10).unwrap();
+        assert!(rx.recv().unwrap() == box 10);
+    }
 
-    test! { fn oneshot_single_thread_try_send_open() {
+    #[test]
+    fn oneshot_single_thread_try_send_open() {
         let (tx, rx) = sync_channel::<int>(1);
         assert_eq!(tx.try_send(10), Ok(()));
-        assert!(rx.recv() == 10);
-    } }
+        assert!(rx.recv().unwrap() == 10);
+    }
 
-    test! { fn oneshot_single_thread_try_send_closed() {
+    #[test]
+    fn oneshot_single_thread_try_send_closed() {
         let (tx, rx) = sync_channel::<int>(0);
         drop(rx);
-        assert_eq!(tx.try_send(10), Err(RecvDisconnected(10)));
-    } }
+        assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10)));
+    }
 
-    test! { fn oneshot_single_thread_try_send_closed2() {
+    #[test]
+    fn oneshot_single_thread_try_send_closed2() {
         let (tx, _rx) = sync_channel::<int>(0);
-        assert_eq!(tx.try_send(10), Err(Full(10)));
-    } }
+        assert_eq!(tx.try_send(10), Err(TrySendError::Full(10)));
+    }
 
-    test! { fn oneshot_single_thread_try_recv_open() {
+    #[test]
+    fn oneshot_single_thread_try_recv_open() {
         let (tx, rx) = sync_channel::<int>(1);
-        tx.send(10);
-        assert!(rx.recv_opt() == Ok(10));
-    } }
+        tx.send(10).unwrap();
+        assert!(rx.recv() == Ok(10));
+    }
 
-    test! { fn oneshot_single_thread_try_recv_closed() {
+    #[test]
+    fn oneshot_single_thread_try_recv_closed() {
         let (tx, rx) = sync_channel::<int>(0);
         drop(tx);
-        assert!(rx.recv_opt() == Err(()));
-    } }
+        assert!(rx.recv().is_err());
+    }
 
-    test! { fn oneshot_single_thread_peek_data() {
+    #[test]
+    fn oneshot_single_thread_peek_data() {
         let (tx, rx) = sync_channel::<int>(1);
-        assert_eq!(rx.try_recv(), Err(Empty));
-        tx.send(10);
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+        tx.send(10).unwrap();
         assert_eq!(rx.try_recv(), Ok(10));
-    } }
+    }
 
-    test! { fn oneshot_single_thread_peek_close() {
+    #[test]
+    fn oneshot_single_thread_peek_close() {
         let (tx, rx) = sync_channel::<int>(0);
         drop(tx);
-        assert_eq!(rx.try_recv(), Err(Disconnected));
-        assert_eq!(rx.try_recv(), Err(Disconnected));
-    } }
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+    }
 
-    test! { fn oneshot_single_thread_peek_open() {
+    #[test]
+    fn oneshot_single_thread_peek_open() {
         let (_tx, rx) = sync_channel::<int>(0);
-        assert_eq!(rx.try_recv(), Err(Empty));
-    } }
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+    }
 
-    test! { fn oneshot_multi_task_recv_then_send() {
+    #[test]
+    fn oneshot_multi_task_recv_then_send() {
         let (tx, rx) = sync_channel::<Box<int>>(0);
-        spawn(move|| {
-            assert!(rx.recv() == box 10);
+        let _t = Thread::spawn(move|| {
+            assert!(rx.recv().unwrap() == box 10);
         });
 
-        tx.send(box 10);
-    } }
+        tx.send(box 10).unwrap();
+    }
 
-    test! { fn oneshot_multi_task_recv_then_close() {
+    #[test]
+    fn oneshot_multi_task_recv_then_close() {
         let (tx, rx) = sync_channel::<Box<int>>(0);
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             drop(tx);
         });
         let res = Thread::spawn(move|| {
-            assert!(rx.recv() == box 10);
+            assert!(rx.recv().unwrap() == box 10);
         }).join();
         assert!(res.is_err());
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_close_stress() {
+    #[test]
+    fn oneshot_multi_thread_close_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = sync_channel::<int>(0);
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 drop(rx);
             });
             drop(tx);
         }
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_send_close_stress() {
+    #[test]
+    fn oneshot_multi_thread_send_close_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = sync_channel::<int>(0);
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 drop(rx);
             });
             let _ = Thread::spawn(move || {
-                tx.send(1);
+                tx.send(1).unwrap();
             }).join();
         }
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_recv_close_stress() {
+    #[test]
+    fn oneshot_multi_thread_recv_close_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = sync_channel::<int>(0);
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 let res = Thread::spawn(move|| {
-                    rx.recv();
+                    rx.recv().unwrap();
                 }).join();
                 assert!(res.is_err());
             });
-            spawn(move|| {
-                spawn(move|| {
+            let _t = Thread::spawn(move|| {
+                Thread::spawn(move|| {
                     drop(tx);
-                });
+                }).detach();
             });
         }
-    } }
+    }
 
-    test! { fn oneshot_multi_thread_send_recv_stress() {
+    #[test]
+    fn oneshot_multi_thread_send_recv_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = sync_channel::<Box<int>>(0);
-            spawn(move|| {
-                tx.send(box 10i);
-            });
-            spawn(move|| {
-                assert!(rx.recv() == box 10i);
+            let _t = Thread::spawn(move|| {
+                tx.send(box 10i).unwrap();
             });
+            assert!(rx.recv().unwrap() == box 10i);
         }
-    } }
+    }
 
-    test! { fn stream_send_recv_stress() {
+    #[test]
+    fn stream_send_recv_stress() {
         for _ in range(0, stress_factor()) {
             let (tx, rx) = sync_channel::<Box<int>>(0);
 
@@ -1839,69 +1862,73 @@ mod sync_tests {
             fn send(tx: SyncSender<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                spawn(move|| {
-                    tx.send(box i);
+                Thread::spawn(move|| {
+                    tx.send(box i).unwrap();
                     send(tx, i + 1);
-                });
+                }).detach();
             }
 
             fn recv(rx: Receiver<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                spawn(move|| {
-                    assert!(rx.recv() == box i);
+                Thread::spawn(move|| {
+                    assert!(rx.recv().unwrap() == box i);
                     recv(rx, i + 1);
-                });
+                }).detach();
             }
         }
-    } }
+    }
 
-    test! { fn recv_a_lot() {
+    #[test]
+    fn recv_a_lot() {
         // Regression test that we don't run out of stack in scheduler context
         let (tx, rx) = sync_channel(10000);
-        for _ in range(0u, 10000) { tx.send(()); }
-        for _ in range(0u, 10000) { rx.recv(); }
-    } }
+        for _ in range(0u, 10000) { tx.send(()).unwrap(); }
+        for _ in range(0u, 10000) { rx.recv().unwrap(); }
+    }
 
-    test! { fn shared_chan_stress() {
+    #[test]
+    fn shared_chan_stress() {
         let (tx, rx) = sync_channel(0);
         let total = stress_factor() + 100;
         for _ in range(0, total) {
             let tx = tx.clone();
-            spawn(move|| {
-                tx.send(());
-            });
+            Thread::spawn(move|| {
+                tx.send(()).unwrap();
+            }).detach();
         }
 
         for _ in range(0, total) {
-            rx.recv();
+            rx.recv().unwrap();
         }
-    } }
+    }
 
-    test! { fn test_nested_recv_iter() {
+    #[test]
+    fn test_nested_recv_iter() {
         let (tx, rx) = sync_channel::<int>(0);
         let (total_tx, total_rx) = sync_channel::<int>(0);
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut acc = 0;
             for x in rx.iter() {
                 acc += x;
             }
-            total_tx.send(acc);
+            total_tx.send(acc).unwrap();
         });
 
-        tx.send(3);
-        tx.send(1);
-        tx.send(2);
+        tx.send(3).unwrap();
+        tx.send(1).unwrap();
+        tx.send(2).unwrap();
         drop(tx);
-        assert_eq!(total_rx.recv(), 6);
-    } }
+        assert_eq!(total_rx.recv().unwrap(), 6);
+    }
 
-    test! { fn test_recv_iter_break() {
+    #[test]
+    fn test_recv_iter_break() {
         let (tx, rx) = sync_channel::<int>(0);
         let (count_tx, count_rx) = sync_channel(0);
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let mut count = 0;
             for x in rx.iter() {
                 if count >= 3 {
@@ -1910,49 +1937,51 @@ mod sync_tests {
                     count += x;
                 }
             }
-            count_tx.send(count);
+            count_tx.send(count).unwrap();
         });
 
-        tx.send(2);
-        tx.send(2);
-        tx.send(2);
+        tx.send(2).unwrap();
+        tx.send(2).unwrap();
+        tx.send(2).unwrap();
         let _ = tx.try_send(2);
         drop(tx);
-        assert_eq!(count_rx.recv(), 4);
-    } }
+        assert_eq!(count_rx.recv().unwrap(), 4);
+    }
 
-    test! { fn try_recv_states() {
+    #[test]
+    fn try_recv_states() {
         let (tx1, rx1) = sync_channel::<int>(1);
         let (tx2, rx2) = sync_channel::<()>(1);
         let (tx3, rx3) = sync_channel::<()>(1);
-        spawn(move|| {
-            rx2.recv();
-            tx1.send(1);
-            tx3.send(());
-            rx2.recv();
+        let _t = Thread::spawn(move|| {
+            rx2.recv().unwrap();
+            tx1.send(1).unwrap();
+            tx3.send(()).unwrap();
+            rx2.recv().unwrap();
             drop(tx1);
-            tx3.send(());
+            tx3.send(()).unwrap();
         });
 
-        assert_eq!(rx1.try_recv(), Err(Empty));
-        tx2.send(());
-        rx3.recv();
+        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+        tx2.send(()).unwrap();
+        rx3.recv().unwrap();
         assert_eq!(rx1.try_recv(), Ok(1));
-        assert_eq!(rx1.try_recv(), Err(Empty));
-        tx2.send(());
-        rx3.recv();
-        assert_eq!(rx1.try_recv(), Err(Disconnected));
-    } }
+        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+        tx2.send(()).unwrap();
+        rx3.recv().unwrap();
+        assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
+    }
 
     // This bug used to end up in a livelock inside of the Receiver destructor
     // because the internal state of the Shared packet was corrupted
-    test! { fn destroy_upgraded_shared_port_when_sender_still_active() {
+    #[test]
+    fn destroy_upgraded_shared_port_when_sender_still_active() {
         let (tx, rx) = sync_channel::<()>(0);
         let (tx2, rx2) = sync_channel::<()>(0);
-        spawn(move|| {
-            rx.recv(); // wait on a oneshot
+        let _t = Thread::spawn(move|| {
+            rx.recv().unwrap(); // wait on a oneshot
             drop(rx);  // destroy a shared
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
         // make sure the other task has gone to sleep
         for _ in range(0u, 5000) { Thread::yield_now(); }
@@ -1960,92 +1989,91 @@ mod sync_tests {
         // upgrade to a shared chan and send a message
         let t = tx.clone();
         drop(tx);
-        t.send(());
+        t.send(()).unwrap();
 
         // wait for the child task to exit before we exit
-        rx2.recv();
-    } }
+        rx2.recv().unwrap();
+    }
 
-    test! { fn send_opt1() {
+    #[test]
+    fn send1() {
         let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| { rx.recv(); });
-        assert_eq!(tx.send_opt(1), Ok(()));
-    } }
+        let _t = Thread::spawn(move|| { rx.recv().unwrap(); });
+        assert_eq!(tx.send(1), Ok(()));
+    }
 
-    test! { fn send_opt2() {
+    #[test]
+    fn send2() {
         let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| { drop(rx); });
-        assert_eq!(tx.send_opt(1), Err(1));
-    } }
+        let _t = Thread::spawn(move|| { drop(rx); });
+        assert!(tx.send(1).is_err());
+    }
 
-    test! { fn send_opt3() {
+    #[test]
+    fn send3() {
         let (tx, rx) = sync_channel::<int>(1);
-        assert_eq!(tx.send_opt(1), Ok(()));
-        spawn(move|| { drop(rx); });
-        assert_eq!(tx.send_opt(1), Err(1));
-    } }
+        assert_eq!(tx.send(1), Ok(()));
+        let _t =Thread::spawn(move|| { drop(rx); });
+        assert!(tx.send(1).is_err());
+    }
 
-    test! { fn send_opt4() {
+    #[test]
+    fn send4() {
         let (tx, rx) = sync_channel::<int>(0);
         let tx2 = tx.clone();
         let (done, donerx) = channel();
         let done2 = done.clone();
-        spawn(move|| {
-            assert_eq!(tx.send_opt(1), Err(1));
-            done.send(());
+        let _t = Thread::spawn(move|| {
+            assert!(tx.send(1).is_err());
+            done.send(()).unwrap();
         });
-        spawn(move|| {
-            assert_eq!(tx2.send_opt(2), Err(2));
-            done2.send(());
+        let _t = Thread::spawn(move|| {
+            assert!(tx2.send(2).is_err());
+            done2.send(()).unwrap();
         });
         drop(rx);
-        donerx.recv();
-        donerx.recv();
-    } }
+        donerx.recv().unwrap();
+        donerx.recv().unwrap();
+    }
 
-    test! { fn try_send1() {
+    #[test]
+    fn try_send1() {
         let (tx, _rx) = sync_channel::<int>(0);
-        assert_eq!(tx.try_send(1), Err(Full(1)));
-    } }
+        assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
+    }
 
-    test! { fn try_send2() {
+    #[test]
+    fn try_send2() {
         let (tx, _rx) = sync_channel::<int>(1);
         assert_eq!(tx.try_send(1), Ok(()));
-        assert_eq!(tx.try_send(1), Err(Full(1)));
-    } }
+        assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
+    }
 
-    test! { fn try_send3() {
+    #[test]
+    fn try_send3() {
         let (tx, rx) = sync_channel::<int>(1);
         assert_eq!(tx.try_send(1), Ok(()));
         drop(rx);
-        assert_eq!(tx.try_send(1), Err(RecvDisconnected(1)));
-    } }
-
-    test! { fn try_send4() {
-        let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| {
-            for _ in range(0u, 1000) { Thread::yield_now(); }
-            assert_eq!(tx.try_send(1), Ok(()));
-        });
-        assert_eq!(rx.recv(), 1);
-    } #[ignore(reason = "flaky on libnative")] }
+        assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1)));
+    }
 
-    test! { fn issue_15761() {
+    #[test]
+    fn issue_15761() {
         fn repro() {
             let (tx1, rx1) = sync_channel::<()>(3);
             let (tx2, rx2) = sync_channel::<()>(3);
 
-            spawn(move|| {
-                rx1.recv();
+            let _t = Thread::spawn(move|| {
+                rx1.recv().unwrap();
                 tx2.try_send(()).unwrap();
             });
 
             tx1.try_send(()).unwrap();
-            rx2.recv();
+            rx2.recv().unwrap();
         }
 
         for _ in range(0u, 100) {
             repro()
         }
-    } }
+    }
 }
diff --git a/src/libstd/comm/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index cddef236664..8945233dac9 100644
--- a/src/libstd/comm/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -153,11 +153,12 @@ impl<T: Send> Drop for Queue<T> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
-
-    use alloc::arc::Arc;
+    use prelude::v1::*;
 
+    use sync::mpsc::channel;
     use super::{Queue, Data, Empty, Inconsistent};
+    use sync::Arc;
+    use thread::Thread;
 
     #[test]
     fn test_full() {
@@ -181,12 +182,12 @@ mod tests {
         for _ in range(0, nthreads) {
             let tx = tx.clone();
             let q = q.clone();
-            spawn(move|| {
+            Thread::spawn(move|| {
                 for i in range(0, nmsgs) {
                     q.push(i);
                 }
-                tx.send(());
-            });
+                tx.send(()).unwrap();
+            }).detach();
         }
 
         let mut i = 0u;
@@ -198,7 +199,7 @@ mod tests {
         }
         drop(tx);
         for _ in range(0, nthreads) {
-            rx.recv();
+            rx.recv().unwrap();
         }
     }
 }
diff --git a/src/libstd/comm/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs
index 9c5a6518845..5f599752a46 100644
--- a/src/libstd/comm/oneshot.rs
+++ b/src/libstd/sync/mpsc/oneshot.rs
@@ -39,8 +39,8 @@ use self::MyUpgrade::*;
 
 use core::prelude::*;
 
-use comm::Receiver;
-use comm::blocking::{mod, SignalToken};
+use sync::mpsc::Receiver;
+use sync::mpsc::blocking::{mod, SignalToken};
 use core::mem;
 use sync::atomic;
 
diff --git a/src/libstd/comm/select.rs b/src/libstd/sync/mpsc/select.rs
index 690b5861c22..43554d7c335 100644
--- a/src/libstd/comm/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -27,18 +27,20 @@
 //! # Example
 //!
 //! ```rust
+//! use std::sync::mpsc::channel;
+//!
 //! let (tx1, rx1) = channel();
 //! let (tx2, rx2) = channel();
 //!
-//! tx1.send(1i);
-//! tx2.send(2i);
+//! tx1.send(1i).unwrap();
+//! tx2.send(2i).unwrap();
 //!
 //! select! {
 //!     val = rx1.recv() => {
-//!         assert_eq!(val, 1i);
+//!         assert_eq!(val.unwrap(), 1i);
 //!     },
 //!     val = rx2.recv() => {
-//!         assert_eq!(val, 2i);
+//!         assert_eq!(val.unwrap(), 2i);
 //!     }
 //! }
 //! ```
@@ -59,8 +61,8 @@ use core::kinds::marker;
 use core::mem;
 use core::uint;
 
-use comm::Receiver;
-use comm::blocking::{mod, SignalToken};
+use sync::mpsc::{Receiver, RecvError};
+use sync::mpsc::blocking::{mod, SignalToken};
 
 /// The "receiver set" of the select interface. This structure is used to manage
 /// a set of receivers which are being selected over.
@@ -245,13 +247,10 @@ impl<'rx, T: Send> Handle<'rx, T> {
     #[inline]
     pub fn id(&self) -> uint { self.id }
 
-    /// Receive a value on the underlying receiver. Has the same semantics as
-    /// `Receiver.recv`
-    pub fn recv(&mut self) -> T { self.rx.recv() }
     /// Block to receive a value on the underlying receiver, returning `Some` on
     /// success or `None` if the channel disconnects. This function has the same
-    /// semantics as `Receiver.recv_opt`
-    pub fn recv_opt(&mut self) -> Result<T, ()> { self.rx.recv_opt() }
+    /// semantics as `Receiver.recv`
+    pub fn recv(&mut self) -> Result<T, RecvError> { self.rx.recv() }
 
     /// Adds this handle to the receiver set that the handle was created from. This
     /// method can be called multiple times, but it has no effect if `add` was
@@ -335,9 +334,10 @@ impl Iterator<*mut Handle<'static, ()>> for Packets {
 #[cfg(test)]
 #[allow(unused_imports)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
 
-    use super::*;
+    use thread::Thread;
+    use sync::mpsc::*;
 
     // Don't use the libstd version so we can pull in the right Select structure
     // (std::comm points at the wrong one)
@@ -345,7 +345,6 @@ mod test {
         (
             $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
         ) => ({
-            use comm::Select;
             let sel = Select::new();
             $( let mut $rx = sel.handle(&$rx); )+
             unsafe {
@@ -357,365 +356,391 @@ mod test {
         })
     }
 
-    test! { fn smoke() {
+    #[test]
+    fn smoke() {
         let (tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<int>();
-        tx1.send(1);
+        tx1.send(1).unwrap();
         select! {
-            foo = rx1.recv() => { assert_eq!(foo, 1); },
+            foo = rx1.recv() => { assert_eq!(foo.unwrap(), 1); },
             _bar = rx2.recv() => { panic!() }
         }
-        tx2.send(2);
+        tx2.send(2).unwrap();
         select! {
             _foo = rx1.recv() => { panic!() },
-            bar = rx2.recv() => { assert_eq!(bar, 2) }
+            bar = rx2.recv() => { assert_eq!(bar.unwrap(), 2) }
         }
         drop(tx1);
         select! {
-            foo = rx1.recv_opt() => { assert_eq!(foo, Err(())); },
+            foo = rx1.recv() => { assert!(foo.is_err()); },
             _bar = rx2.recv() => { panic!() }
         }
         drop(tx2);
         select! {
-            bar = rx2.recv_opt() => { assert_eq!(bar, Err(())); }
+            bar = rx2.recv() => { assert!(bar.is_err()); }
         }
-    } }
+    }
 
-    test! { fn smoke2() {
+    #[test]
+    fn smoke2() {
         let (_tx1, rx1) = channel::<int>();
         let (_tx2, rx2) = channel::<int>();
         let (_tx3, rx3) = channel::<int>();
         let (_tx4, rx4) = channel::<int>();
         let (tx5, rx5) = channel::<int>();
-        tx5.send(4);
+        tx5.send(4).unwrap();
         select! {
             _foo = rx1.recv() => { panic!("1") },
             _foo = rx2.recv() => { panic!("2") },
             _foo = rx3.recv() => { panic!("3") },
             _foo = rx4.recv() => { panic!("4") },
-            foo = rx5.recv() => { assert_eq!(foo, 4); }
+            foo = rx5.recv() => { assert_eq!(foo.unwrap(), 4); }
         }
-    } }
+    }
 
-    test! { fn closed() {
+    #[test]
+    fn closed() {
         let (_tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<int>();
         drop(tx2);
 
         select! {
-            _a1 = rx1.recv_opt() => { panic!() },
-            a2 = rx2.recv_opt() => { assert_eq!(a2, Err(())); }
+            _a1 = rx1.recv() => { panic!() },
+            a2 = rx2.recv() => { assert!(a2.is_err()); }
         }
-    } }
+    }
 
-    test! { fn unblocks() {
+    #[test]
+    fn unblocks() {
         let (tx1, rx1) = channel::<int>();
         let (_tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<int>();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             for _ in range(0u, 20) { Thread::yield_now(); }
-            tx1.send(1);
-            rx3.recv();
+            tx1.send(1).unwrap();
+            rx3.recv().unwrap();
             for _ in range(0u, 20) { Thread::yield_now(); }
         });
 
         select! {
-            a = rx1.recv() => { assert_eq!(a, 1); },
+            a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
             _b = rx2.recv() => { panic!() }
         }
-        tx3.send(1);
+        tx3.send(1).unwrap();
         select! {
-            a = rx1.recv_opt() => { assert_eq!(a, Err(())); },
+            a = rx1.recv() => { assert!(a.is_err()) },
             _b = rx2.recv() => { panic!() }
         }
-    } }
+    }
 
-    test! { fn both_ready() {
+    #[test]
+    fn both_ready() {
         let (tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             for _ in range(0u, 20) { Thread::yield_now(); }
-            tx1.send(1);
-            tx2.send(2);
-            rx3.recv();
+            tx1.send(1).unwrap();
+            tx2.send(2).unwrap();
+            rx3.recv().unwrap();
         });
 
         select! {
-            a = rx1.recv() => { assert_eq!(a, 1); },
-            a = rx2.recv() => { assert_eq!(a, 2); }
+            a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
+            a = rx2.recv() => { assert_eq!(a.unwrap(), 2); }
         }
         select! {
-            a = rx1.recv() => { assert_eq!(a, 1); },
-            a = rx2.recv() => { assert_eq!(a, 2); }
+            a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
+            a = rx2.recv() => { assert_eq!(a.unwrap(), 2); }
         }
-        assert_eq!(rx1.try_recv(), Err(Empty));
-        assert_eq!(rx2.try_recv(), Err(Empty));
-        tx3.send(());
-    } }
+        assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+        assert_eq!(rx2.try_recv(), Err(TryRecvError::Empty));
+        tx3.send(()).unwrap();
+    }
 
-    test! { fn stress() {
+    #[test]
+    fn stress() {
         static AMT: int = 10000;
         let (tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             for i in range(0, AMT) {
                 if i % 2 == 0 {
-                    tx1.send(i);
+                    tx1.send(i).unwrap();
                 } else {
-                    tx2.send(i);
+                    tx2.send(i).unwrap();
                 }
-                rx3.recv();
+                rx3.recv().unwrap();
             }
         });
 
         for i in range(0, AMT) {
             select! {
-                i1 = rx1.recv() => { assert!(i % 2 == 0 && i == i1); },
-                i2 = rx2.recv() => { assert!(i % 2 == 1 && i == i2); }
+                i1 = rx1.recv() => { assert!(i % 2 == 0 && i == i1.unwrap()); },
+                i2 = rx2.recv() => { assert!(i % 2 == 1 && i == i2.unwrap()); }
             }
-            tx3.send(());
+            tx3.send(()).unwrap();
         }
-    } }
+    }
 
-    test! { fn cloning() {
+    #[test]
+    fn cloning() {
         let (tx1, rx1) = channel::<int>();
         let (_tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        spawn(move|| {
-            rx3.recv();
+        let _t = Thread::spawn(move|| {
+            rx3.recv().unwrap();
             tx1.clone();
-            assert_eq!(rx3.try_recv(), Err(Empty));
-            tx1.send(2);
-            rx3.recv();
+            assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
+            tx1.send(2).unwrap();
+            rx3.recv().unwrap();
         });
 
-        tx3.send(());
+        tx3.send(()).unwrap();
         select! {
             _i1 = rx1.recv() => {},
             _i2 = rx2.recv() => panic!()
         }
-        tx3.send(());
-    } }
+        tx3.send(()).unwrap();
+    }
 
-    test! { fn cloning2() {
+    #[test]
+    fn cloning2() {
         let (tx1, rx1) = channel::<int>();
         let (_tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        spawn(move|| {
-            rx3.recv();
+        let _t = Thread::spawn(move|| {
+            rx3.recv().unwrap();
             tx1.clone();
-            assert_eq!(rx3.try_recv(), Err(Empty));
-            tx1.send(2);
-            rx3.recv();
+            assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
+            tx1.send(2).unwrap();
+            rx3.recv().unwrap();
         });
 
-        tx3.send(());
+        tx3.send(()).unwrap();
         select! {
             _i1 = rx1.recv() => {},
             _i2 = rx2.recv() => panic!()
         }
-        tx3.send(());
-    } }
+        tx3.send(()).unwrap();
+    }
 
-    test! { fn cloning3() {
+    #[test]
+    fn cloning3() {
         let (tx1, rx1) = channel::<()>();
         let (tx2, rx2) = channel::<()>();
         let (tx3, rx3) = channel::<()>();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let s = Select::new();
             let mut h1 = s.handle(&rx1);
             let mut h2 = s.handle(&rx2);
             unsafe { h2.add(); }
             unsafe { h1.add(); }
             assert_eq!(s.wait(), h2.id);
-            tx3.send(());
+            tx3.send(()).unwrap();
         });
 
         for _ in range(0u, 1000) { Thread::yield_now(); }
         drop(tx1.clone());
-        tx2.send(());
-        rx3.recv();
-    } }
+        tx2.send(()).unwrap();
+        rx3.recv().unwrap();
+    }
 
-    test! { fn preflight1() {
+    #[test]
+    fn preflight1() {
         let (tx, rx) = channel();
-        tx.send(());
+        tx.send(()).unwrap();
         select! {
-            () = rx.recv() => {}
+            _n = rx.recv() => {}
         }
-    } }
+    }
 
-    test! { fn preflight2() {
+    #[test]
+    fn preflight2() {
         let (tx, rx) = channel();
-        tx.send(());
-        tx.send(());
+        tx.send(()).unwrap();
+        tx.send(()).unwrap();
         select! {
-            () = rx.recv() => {}
+            _n = rx.recv() => {}
         }
-    } }
+    }
 
-    test! { fn preflight3() {
+    #[test]
+    fn preflight3() {
         let (tx, rx) = channel();
         drop(tx.clone());
-        tx.send(());
+        tx.send(()).unwrap();
         select! {
-            () = rx.recv() => {}
+            _n = rx.recv() => {}
         }
-    } }
+    }
 
-    test! { fn preflight4() {
+    #[test]
+    fn preflight4() {
         let (tx, rx) = channel();
-        tx.send(());
+        tx.send(()).unwrap();
         let s = Select::new();
         let mut h = s.handle(&rx);
         unsafe { h.add(); }
         assert_eq!(s.wait2(false), h.id);
-    } }
+    }
 
-    test! { fn preflight5() {
+    #[test]
+    fn preflight5() {
         let (tx, rx) = channel();
-        tx.send(());
-        tx.send(());
+        tx.send(()).unwrap();
+        tx.send(()).unwrap();
         let s = Select::new();
         let mut h = s.handle(&rx);
         unsafe { h.add(); }
         assert_eq!(s.wait2(false), h.id);
-    } }
+    }
 
-    test! { fn preflight6() {
+    #[test]
+    fn preflight6() {
         let (tx, rx) = channel();
         drop(tx.clone());
-        tx.send(());
+        tx.send(()).unwrap();
         let s = Select::new();
         let mut h = s.handle(&rx);
         unsafe { h.add(); }
         assert_eq!(s.wait2(false), h.id);
-    } }
+    }
 
-    test! { fn preflight7() {
+    #[test]
+    fn preflight7() {
         let (tx, rx) = channel::<()>();
         drop(tx);
         let s = Select::new();
         let mut h = s.handle(&rx);
         unsafe { h.add(); }
         assert_eq!(s.wait2(false), h.id);
-    } }
+    }
 
-    test! { fn preflight8() {
+    #[test]
+    fn preflight8() {
         let (tx, rx) = channel();
-        tx.send(());
+        tx.send(()).unwrap();
         drop(tx);
-        rx.recv();
+        rx.recv().unwrap();
         let s = Select::new();
         let mut h = s.handle(&rx);
         unsafe { h.add(); }
         assert_eq!(s.wait2(false), h.id);
-    } }
+    }
 
-    test! { fn preflight9() {
+    #[test]
+    fn preflight9() {
         let (tx, rx) = channel();
         drop(tx.clone());
-        tx.send(());
+        tx.send(()).unwrap();
         drop(tx);
-        rx.recv();
+        rx.recv().unwrap();
         let s = Select::new();
         let mut h = s.handle(&rx);
         unsafe { h.add(); }
         assert_eq!(s.wait2(false), h.id);
-    } }
+    }
 
-    test! { fn oneshot_data_waiting() {
+    #[test]
+    fn oneshot_data_waiting() {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             select! {
-                () = rx1.recv() => {}
+                _n = rx1.recv() => {}
             }
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         for _ in range(0u, 100) { Thread::yield_now() }
-        tx1.send(());
-        rx2.recv();
-    } }
+        tx1.send(()).unwrap();
+        rx2.recv().unwrap();
+    }
 
-    test! { fn stream_data_waiting() {
+    #[test]
+    fn stream_data_waiting() {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        tx1.send(());
-        tx1.send(());
-        rx1.recv();
-        rx1.recv();
-        spawn(move|| {
+        tx1.send(()).unwrap();
+        tx1.send(()).unwrap();
+        rx1.recv().unwrap();
+        rx1.recv().unwrap();
+        let _t = Thread::spawn(move|| {
             select! {
-                () = rx1.recv() => {}
+                _n = rx1.recv() => {}
             }
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         for _ in range(0u, 100) { Thread::yield_now() }
-        tx1.send(());
-        rx2.recv();
-    } }
+        tx1.send(()).unwrap();
+        rx2.recv().unwrap();
+    }
 
-    test! { fn shared_data_waiting() {
+    #[test]
+    fn shared_data_waiting() {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
         drop(tx1.clone());
-        tx1.send(());
-        rx1.recv();
-        spawn(move|| {
+        tx1.send(()).unwrap();
+        rx1.recv().unwrap();
+        let _t = Thread::spawn(move|| {
             select! {
-                () = rx1.recv() => {}
+                _n = rx1.recv() => {}
             }
-            tx2.send(());
+            tx2.send(()).unwrap();
         });
 
         for _ in range(0u, 100) { Thread::yield_now() }
-        tx1.send(());
-        rx2.recv();
-    } }
+        tx1.send(()).unwrap();
+        rx2.recv().unwrap();
+    }
 
-    test! { fn sync1() {
+    #[test]
+    fn sync1() {
         let (tx, rx) = sync_channel::<int>(1);
-        tx.send(1);
+        tx.send(1).unwrap();
         select! {
-            n = rx.recv() => { assert_eq!(n, 1); }
+            n = rx.recv() => { assert_eq!(n.unwrap(), 1); }
         }
-    } }
+    }
 
-    test! { fn sync2() {
+    #[test]
+    fn sync2() {
         let (tx, rx) = sync_channel::<int>(0);
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             for _ in range(0u, 100) { Thread::yield_now() }
-            tx.send(1);
+            tx.send(1).unwrap();
         });
         select! {
-            n = rx.recv() => { assert_eq!(n, 1); }
+            n = rx.recv() => { assert_eq!(n.unwrap(), 1); }
         }
-    } }
+    }
 
-    test! { fn sync3() {
+    #[test]
+    fn sync3() {
         let (tx1, rx1) = sync_channel::<int>(0);
         let (tx2, rx2): (Sender<int>, Receiver<int>) = channel();
-        spawn(move|| { tx1.send(1); });
-        spawn(move|| { tx2.send(2); });
+        let _t = Thread::spawn(move|| { tx1.send(1).unwrap(); });
+        let _t = Thread::spawn(move|| { tx2.send(2).unwrap(); });
         select! {
             n = rx1.recv() => {
+                let n = n.unwrap();
                 assert_eq!(n, 1);
-                assert_eq!(rx2.recv(), 2);
+                assert_eq!(rx2.recv().unwrap(), 2);
             },
             n = rx2.recv() => {
+                let n = n.unwrap();
                 assert_eq!(n, 2);
-                assert_eq!(rx1.recv(), 1);
+                assert_eq!(rx1.recv().unwrap(), 1);
             }
         }
-    } }
+    }
 }
diff --git a/src/libstd/comm/shared.rs b/src/libstd/sync/mpsc/shared.rs
index 3f23ec5dc66..e15c38cf9a1 100644
--- a/src/libstd/comm/shared.rs
+++ b/src/libstd/sync/mpsc/shared.rs
@@ -26,10 +26,10 @@ use core::cmp;
 use core::int;
 
 use sync::{atomic, Mutex, MutexGuard};
-use comm::mpsc_queue as mpsc;
-use comm::blocking::{mod, SignalToken};
-use comm::select::StartResult;
-use comm::select::StartResult::*;
+use sync::mpsc::mpsc_queue as mpsc;
+use sync::mpsc::blocking::{mod, SignalToken};
+use sync::mpsc::select::StartResult;
+use sync::mpsc::select::StartResult::*;
 use thread::Thread;
 
 const DISCONNECTED: int = int::MIN;
diff --git a/src/libstd/comm/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index becb78063ae..15624601157 100644
--- a/src/libstd/comm/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -240,10 +240,12 @@ impl<T: Send> Drop for Queue<T> {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
 
     use sync::Arc;
     use super::Queue;
+    use thread::Thread;
+    use sync::mpsc::channel;
 
     #[test]
     fn smoke() {
@@ -320,7 +322,7 @@ mod test {
 
             let (tx, rx) = channel();
             let q2 = q.clone();
-            spawn(move|| {
+            let _t = Thread::spawn(move|| {
                 for _ in range(0u, 100000) {
                     loop {
                         match q2.pop() {
@@ -330,12 +332,12 @@ mod test {
                         }
                     }
                 }
-                tx.send(());
+                tx.send(()).unwrap();
             });
             for _ in range(0i, 100000) {
                 q.push(1);
             }
-            rx.recv();
+            rx.recv().unwrap();
         }
     }
 }
diff --git a/src/libstd/comm/stream.rs b/src/libstd/sync/mpsc/stream.rs
index b68f626060e..01b799283ee 100644
--- a/src/libstd/comm/stream.rs
+++ b/src/libstd/sync/mpsc/stream.rs
@@ -28,10 +28,10 @@ use core::cmp;
 use core::int;
 use thread::Thread;
 
+use sync::mpsc::blocking::{mod, SignalToken};
+use sync::mpsc::spsc_queue as spsc;
+use sync::mpsc::Receiver;
 use sync::atomic;
-use comm::spsc_queue as spsc;
-use comm::Receiver;
-use comm::blocking::{mod, SignalToken};
 
 const DISCONNECTED: int = int::MIN;
 #[cfg(test)]
diff --git a/src/libstd/comm/sync.rs b/src/libstd/sync/mpsc/sync.rs
index a8004155af0..98f1c4c46f9 100644
--- a/src/libstd/comm/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -42,8 +42,8 @@ use vec::Vec;
 use core::mem;
 
 use sync::{atomic, Mutex, MutexGuard};
-use comm::blocking::{mod, WaitToken, SignalToken};
-use comm::select::StartResult::{mod, Installed, Abort};
+use sync::mpsc::blocking::{mod, WaitToken, SignalToken};
+use sync::mpsc::select::StartResult::{mod, Installed, Abort};
 
 pub struct Packet<T> {
     /// Only field outside of the mutex. Just done for kicks, but mainly because
@@ -204,14 +204,14 @@ impl<T: Send> Packet<T> {
     pub fn try_send(&self, t: T) -> Result<(), super::TrySendError<T>> {
         let mut guard = self.lock.lock().unwrap();
         if guard.disconnected {
-            Err(super::RecvDisconnected(t))
+            Err(super::TrySendError::Disconnected(t))
         } else if guard.buf.size() == guard.buf.cap() {
-            Err(super::Full(t))
+            Err(super::TrySendError::Full(t))
         } else if guard.cap == 0 {
             // With capacity 0, even though we have buffer space we can't
             // transfer the data unless there's a receiver waiting.
             match mem::replace(&mut guard.blocker, NoneBlocked) {
-                NoneBlocked => Err(super::Full(t)),
+                NoneBlocked => Err(super::TrySendError::Full(t)),
                 BlockedSender(..) => unreachable!(),
                 BlockedReceiver(token) => {
                     guard.buf.enqueue(t);
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 52004bb4a8f..f9f9a809221 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 
 use cell::UnsafeCell;
 use kinds::marker;
+use ops::{Deref, DerefMut};
 use sync::poison::{mod, TryLockError, TryLockResult, LockResult};
 use sys_common::mutex as sys;
 
@@ -47,6 +48,8 @@ use sys_common::mutex as sys;
 /// ```rust
 /// use std::sync::{Arc, Mutex};
 /// use std::thread::Thread;
+/// use std::sync::mpsc::channel;
+///
 /// const N: uint = 10;
 ///
 /// // Spawn a few threads to increment a shared variable (non-atomically), and
@@ -69,13 +72,13 @@ use sys_common::mutex as sys;
 ///         let mut data = data.lock().unwrap();
 ///         *data += 1;
 ///         if *data == N {
-///             tx.send(());
+///             tx.send(()).unwrap();
 ///         }
 ///         // the lock is unlocked here when `data` goes out of scope.
 ///     }).detach();
 /// }
 ///
-/// rx.recv();
+/// rx.recv().unwrap();
 /// ```
 ///
 /// To recover from a poisoned mutex:
@@ -288,12 +291,14 @@ impl<'mutex, T> MutexGuard<'mutex, T> {
     }
 }
 
-impl<'mutex, T> Deref<T> for MutexGuard<'mutex, T> {
+impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
+    type Target = T;
+
     fn deref<'a>(&'a self) -> &'a T {
         unsafe { &*self.__data.get() }
     }
 }
-impl<'mutex, T> DerefMut<T> for MutexGuard<'mutex, T> {
+impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         unsafe { &mut *self.__data.get() }
     }
@@ -320,10 +325,11 @@ pub fn guard_poison<'a, T>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
 
-    use thread::Thread;
+    use sync::mpsc::channel;
     use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar};
+    use thread::Thread;
 
     struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
 
@@ -366,14 +372,14 @@ mod test {
         let (tx, rx) = channel();
         for _ in range(0, K) {
             let tx2 = tx.clone();
-            spawn(move|| { inc(); tx2.send(()); });
+            Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }).detach();
             let tx2 = tx.clone();
-            spawn(move|| { inc(); tx2.send(()); });
+            Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); }).detach();
         }
 
         drop(tx);
         for _ in range(0, 2 * K) {
-            rx.recv();
+            rx.recv().unwrap();
         }
         assert_eq!(unsafe {CNT}, J * K * 2);
         unsafe {
@@ -392,9 +398,9 @@ mod test {
         let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
         let packet2 = Packet(packet.0.clone());
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             // wait until parent gets in
-            rx.recv();
+            rx.recv().unwrap();
             let &(ref lock, ref cvar) = &*packet2.0;
             let mut lock = lock.lock().unwrap();
             *lock = true;
@@ -403,7 +409,7 @@ mod test {
 
         let &(ref lock, ref cvar) = &*packet.0;
         let mut lock = lock.lock().unwrap();
-        tx.send(());
+        tx.send(()).unwrap();
         assert!(!*lock);
         while !*lock {
             lock = cvar.wait(lock).unwrap();
@@ -416,8 +422,8 @@ mod test {
         let packet2 = Packet(packet.0.clone());
         let (tx, rx) = channel();
 
-        spawn(move|| {
-            rx.recv();
+        let _t = Thread::spawn(move || -> () {
+            rx.recv().unwrap();
             let &(ref lock, ref cvar) = &*packet2.0;
             let _g = lock.lock().unwrap();
             cvar.notify_one();
@@ -427,7 +433,7 @@ mod test {
 
         let &(ref lock, ref cvar) = &*packet.0;
         let mut lock = lock.lock().unwrap();
-        tx.send(());
+        tx.send(()).unwrap();
         while *lock == 1 {
             match cvar.wait(lock) {
                 Ok(l) => {
@@ -443,7 +449,7 @@ mod test {
     fn test_mutex_arc_poison() {
         let arc = Arc::new(Mutex::new(1i));
         let arc2 = arc.clone();
-        Thread::spawn(move|| {
+        let _ = Thread::spawn(move|| {
             let lock = arc2.lock().unwrap();
             assert_eq!(*lock, 2);
         }).join();
@@ -457,13 +463,13 @@ mod test {
         let arc = Arc::new(Mutex::new(1i));
         let arc2 = Arc::new(Mutex::new(arc));
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let lock = arc2.lock().unwrap();
-            let lock2 = lock.deref().lock().unwrap();
+            let lock2 = lock.lock().unwrap();
             assert_eq!(*lock2, 1);
-            tx.send(());
+            tx.send(()).unwrap();
         });
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 4d9fbb59908..9e9a17e482f 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -32,10 +32,11 @@ use sync::{StaticMutex, MUTEX_INIT};
 ///
 /// static START: Once = ONCE_INIT;
 ///
-/// START.doit(|| {
+/// START.call_once(|| {
 ///     // run initialization here
 /// });
 /// ```
+#[stable]
 pub struct Once {
     mutex: StaticMutex,
     cnt: atomic::AtomicInt,
@@ -45,23 +46,25 @@ pub struct Once {
 unsafe impl Sync for Once {}
 
 /// Initialization value for static `Once` values.
+#[stable]
 pub const ONCE_INIT: Once = Once {
     mutex: MUTEX_INIT,
-    cnt: atomic::INIT_ATOMIC_INT,
-    lock_cnt: atomic::INIT_ATOMIC_INT,
+    cnt: atomic::ATOMIC_INT_INIT,
+    lock_cnt: atomic::ATOMIC_INT_INIT,
 };
 
 impl Once {
     /// Perform an initialization routine once and only once. The given closure
-    /// will be executed if this is the first time `doit` has been called, and
-    /// otherwise the routine will *not* be invoked.
+    /// will be executed if this is the first time `call_once` has been called,
+    /// and otherwise the routine will *not* be invoked.
     ///
     /// This method will block the calling task if another initialization
     /// routine is currently running.
     ///
     /// When this function returns, it is guaranteed that some initialization
     /// has run and completed (it may not be the closure specified).
-    pub fn doit<F>(&'static self, f: F) where F: FnOnce() {
+    #[stable]
+    pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
         // Optimize common path: load is much cheaper than fetch_add.
         if self.cnt.load(atomic::SeqCst) < 0 {
             return
@@ -91,13 +94,13 @@ impl Once {
         //
         // It is crucial that the negative value is swapped in *after* the
         // initialization routine has completed because otherwise new threads
-        // calling `doit` will return immediately before the initialization has
-        // completed.
+        // calling `call_once` will return immediately before the initialization
+        // has completed.
 
         let prev = self.cnt.fetch_add(1, atomic::SeqCst);
         if prev < 0 {
             // Make sure we never overflow, we'll never have int::MIN
-            // simultaneous calls to `doit` to make this value go back to 0
+            // simultaneous calls to `call_once` to make this value go back to 0
             self.cnt.store(int::MIN, atomic::SeqCst);
             return
         }
@@ -118,22 +121,27 @@ impl Once {
             unsafe { self.mutex.destroy() }
         }
     }
+
+    /// Deprecated
+    #[deprecated = "renamed to `call_once`"]
+    pub fn doit<F>(&'static self, f: F) where F: FnOnce() { self.call_once(f) }
 }
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
 
     use thread::Thread;
     use super::{ONCE_INIT, Once};
+    use sync::mpsc::channel;
 
     #[test]
     fn smoke_once() {
         static O: Once = ONCE_INIT;
         let mut a = 0i;
-        O.doit(|| a += 1);
+        O.call_once(|| a += 1);
         assert_eq!(a, 1);
-        O.doit(|| a += 1);
+        O.call_once(|| a += 1);
         assert_eq!(a, 1);
     }
 
@@ -145,21 +153,21 @@ mod test {
         let (tx, rx) = channel();
         for _ in range(0u, 10) {
             let tx = tx.clone();
-            spawn(move|| {
+            Thread::spawn(move|| {
                 for _ in range(0u, 4) { Thread::yield_now() }
                 unsafe {
-                    O.doit(|| {
+                    O.call_once(|| {
                         assert!(!run);
                         run = true;
                     });
                     assert!(run);
                 }
-                tx.send(());
-            });
+                tx.send(()).unwrap();
+            }).detach();
         }
 
         unsafe {
-            O.doit(|| {
+            O.call_once(|| {
                 assert!(!run);
                 run = true;
             });
@@ -167,7 +175,7 @@ mod test {
         }
 
         for _ in range(0u, 10) {
-            rx.recv();
+            rx.recv().unwrap();
         }
     }
 }
diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs
index edf16d99f49..6e4df118209 100644
--- a/src/libstd/sync/poison.rs
+++ b/src/libstd/sync/poison.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 
 use cell::UnsafeCell;
 use error::FromError;
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 7f3c77c97ad..431aeb9cae9 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 
 use cell::UnsafeCell;
 use kinds::marker;
+use ops::{Deref, DerefMut};
 use sync::poison::{mod, LockResult, TryLockError, TryLockResult};
 use sys_common::rwlock as sys;
 
@@ -326,13 +327,17 @@ impl<'rwlock, T> RWLockWriteGuard<'rwlock, T> {
     }
 }
 
-impl<'rwlock, T> Deref<T> for RWLockReadGuard<'rwlock, T> {
+impl<'rwlock, T> Deref for RWLockReadGuard<'rwlock, T> {
+    type Target = T;
+
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-impl<'rwlock, T> Deref<T> for RWLockWriteGuard<'rwlock, T> {
+impl<'rwlock, T> Deref for RWLockWriteGuard<'rwlock, T> {
+    type Target = T;
+
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-impl<'rwlock, T> DerefMut<T> for RWLockWriteGuard<'rwlock, T> {
+impl<'rwlock, T> DerefMut for RWLockWriteGuard<'rwlock, T> {
     fn deref_mut(&mut self) -> &mut T {
         unsafe { &mut *self.__data.get() }
     }
@@ -355,9 +360,10 @@ impl<'a, T> Drop for RWLockWriteGuard<'a, T> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
 
     use rand::{mod, Rng};
+    use sync::mpsc::channel;
     use thread::Thread;
     use sync::{Arc, RWLock, StaticRWLock, RWLOCK_INIT};
 
@@ -389,7 +395,7 @@ mod tests {
         let (tx, rx) = channel::<()>();
         for _ in range(0, N) {
             let tx = tx.clone();
-            spawn(move|| {
+            Thread::spawn(move|| {
                 let mut rng = rand::thread_rng();
                 for _ in range(0, M) {
                     if rng.gen_weighted_bool(N) {
@@ -399,10 +405,10 @@ mod tests {
                     }
                 }
                 drop(tx);
-            });
+            }).detach();
         }
         drop(tx);
-        let _ = rx.recv_opt();
+        let _ = rx.recv();
         unsafe { R.destroy(); }
     }
 
@@ -465,7 +471,7 @@ mod tests {
                 Thread::yield_now();
                 *lock = tmp + 1;
             }
-            tx.send(());
+            tx.send(()).unwrap();
         }).detach();
 
         // Readers try to catch the writer in the act
@@ -484,7 +490,7 @@ mod tests {
         }
 
         // Wait for writer to finish
-        rx.recv();
+        rx.recv().unwrap();
         let lock = arc.read().unwrap();
         assert_eq!(*lock, 10);
     }
diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs
index e3b683a6ccb..c0ff674ba0f 100644
--- a/src/libstd/sync/semaphore.rs
+++ b/src/libstd/sync/semaphore.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable = "the interaction between semaphores and the acquisition/release \
+               of resources is currently unclear"]
+
 use ops::Drop;
 use sync::{Mutex, Condvar};
 
@@ -104,10 +107,12 @@ impl<'a> Drop for SemaphoreGuard<'a> {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
 
     use sync::Arc;
     use super::Semaphore;
+    use sync::mpsc::channel;
+    use thread::Thread;
 
     #[test]
     fn test_sem_acquire_release() {
@@ -127,7 +132,7 @@ mod tests {
     fn test_sem_as_mutex() {
         let s = Arc::new(Semaphore::new(1));
         let s2 = s.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _g = s2.access();
         });
         let _g = s.access();
@@ -139,9 +144,9 @@ mod tests {
         let (tx, rx) = channel();
         let s = Arc::new(Semaphore::new(0));
         let s2 = s.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             s2.acquire();
-            tx.send(());
+            tx.send(()).unwrap();
         });
         s.release();
         let _ = rx.recv();
@@ -150,12 +155,12 @@ mod tests {
         let (tx, rx) = channel();
         let s = Arc::new(Semaphore::new(0));
         let s2 = s.clone();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             s2.release();
             let _ = rx.recv();
         });
         s.acquire();
-        tx.send(());
+        tx.send(()).unwrap();
     }
 
     #[test]
@@ -166,14 +171,14 @@ mod tests {
         let s2 = s.clone();
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             let _g = s2.access();
             let _ = rx2.recv();
-            tx1.send(());
+            tx1.send(()).unwrap();
         });
         let _g = s.access();
-        tx2.send(());
-        let _ = rx1.recv();
+        tx2.send(()).unwrap();
+        rx1.recv().unwrap();
     }
 
     #[test]
@@ -183,13 +188,13 @@ mod tests {
         let (tx, rx) = channel();
         {
             let _g = s.access();
-            spawn(move|| {
-                tx.send(());
+            Thread::spawn(move|| {
+                tx.send(()).unwrap();
                 drop(s2.access());
-                tx.send(());
-            });
-            rx.recv(); // wait for child to come alive
+                tx.send(()).unwrap();
+            }).detach();
+            rx.recv().unwrap(); // wait for child to come alive
         }
-        rx.recv(); // wait for child to be done
+        rx.recv().unwrap(); // wait for child to be done
     }
 }
diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs
index ee534f6cdde..088827dc084 100644
--- a/src/libstd/sync/task_pool.rs
+++ b/src/libstd/sync/task_pool.rs
@@ -10,11 +10,16 @@
 
 //! Abstraction of a thread pool for basic parallelism.
 
+#![unstable = "the semantics of a failing task and whether a thread is \
+               re-attached to a thread pool are somewhat unclear, and the \
+               utility of this type in `std::sync` is questionable with \
+               respect to the jobs of other primitives"]
+
 use core::prelude::*;
 
-use thread::Thread;
-use comm::{channel, Sender, Receiver};
 use sync::{Arc, Mutex};
+use sync::mpsc::{channel, Sender, Receiver};
+use thread::Thread;
 use thunk::Thunk;
 
 struct Sentinel<'a> {
@@ -53,8 +58,9 @@ impl<'a> Drop for Sentinel<'a> {
 /// # Example
 ///
 /// ```rust
-/// # use std::sync::TaskPool;
-/// # use std::iter::AdditiveIterator;
+/// use std::sync::TaskPool;
+/// use std::iter::AdditiveIterator;
+/// use std::sync::mpsc::channel;
 ///
 /// let pool = TaskPool::new(4u);
 ///
@@ -62,7 +68,7 @@ impl<'a> Drop for Sentinel<'a> {
 /// for _ in range(0, 8u) {
 ///     let tx = tx.clone();
 ///     pool.execute(move|| {
-///         tx.send(1u);
+///         tx.send(1u).unwrap();
 ///     });
 /// }
 ///
@@ -100,7 +106,7 @@ impl TaskPool {
     pub fn execute<F>(&self, job: F)
         where F : FnOnce(), F : Send
     {
-        self.jobs.send(Thunk::new(job));
+        self.jobs.send(Thunk::new(job)).unwrap();
     }
 }
 
@@ -114,7 +120,7 @@ fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk>>>) {
                 // Only lock jobs for the time it takes
                 // to get a job, not run it.
                 let lock = jobs.lock().unwrap();
-                lock.recv_opt()
+                lock.recv()
             };
 
             match message {
@@ -131,8 +137,9 @@ fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk>>>) {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
     use super::*;
+    use sync::mpsc::channel;
 
     const TEST_TASKS: uint = 4u;
 
@@ -146,7 +153,7 @@ mod test {
         for _ in range(0, TEST_TASKS) {
             let tx = tx.clone();
             pool.execute(move|| {
-                tx.send(1u);
+                tx.send(1u).unwrap();
             });
         }
 
@@ -175,7 +182,7 @@ mod test {
         for _ in range(0, TEST_TASKS) {
             let tx = tx.clone();
             pool.execute(move|| {
-                tx.send(1u);
+                tx.send(1u).unwrap();
             });
         }
 
diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs
index 866bf1d8a7d..d4039fd96ff 100644
--- a/src/libstd/sys/common/backtrace.rs
+++ b/src/libstd/sys/common/backtrace.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 
 use io::IoResult;
 
diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs
index 9ef1c33312f..bdf1bf3dfd0 100644
--- a/src/libstd/sys/common/helper_thread.rs
+++ b/src/libstd/sys/common/helper_thread.rs
@@ -20,12 +20,13 @@
 //! can be created in the future and there must be no active timers at that
 //! time.
 
-use prelude::*;
+use prelude::v1::*;
 
 use cell::UnsafeCell;
 use mem;
-use sync::{StaticMutex, StaticCondvar};
 use rt;
+use sync::{StaticMutex, StaticCondvar};
+use sync::mpsc::{channel, Sender, Receiver};
 use sys::helper_signal;
 
 use thread::Thread;
@@ -117,7 +118,7 @@ impl<M: Send> Helper<M> {
             // message. Otherwise it could wake up and go to sleep before we
             // send the message.
             assert!(!self.chan.get().is_null());
-            (**self.chan.get()).send(msg);
+            (**self.chan.get()).send(msg).unwrap();
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
         }
     }
diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs
index dc0ad08cdbe..97015f74a4a 100644
--- a/src/libstd/sys/common/mod.rs
+++ b/src/libstd/sys/common/mod.rs
@@ -12,7 +12,7 @@
 #![allow(dead_code)]
 
 use io::{mod, IoError, IoResult};
-use prelude::*;
+use prelude::v1::*;
 use sys::{last_error, retry};
 use c_str::CString;
 use num::Int;
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 259c15b5f06..cb0c5581abd 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -8,24 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
 use self::SocketStatus::*;
 use self::InAddr::*;
 
-use alloc::arc::Arc;
+use c_str::ToCStr;
+use io::net::addrinfo;
+use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
+use io::{IoResult, IoError};
 use libc::{mod, c_char, c_int};
 use c_str::CString;
 use mem;
 use num::Int;
 use ptr::{mod, null, null_mut};
-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 sync::{Arc, Mutex, MutexGuard};
 use sys_common::{mod, keep_going, short_write, timeout};
-use prelude::*;
 use cmp;
 use io;
 
diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs
index 8c76eb1504d..92b936e74f6 100644
--- a/src/libstd/sys/common/thread_info.rs
+++ b/src/libstd/sys/common/thread_info.rs
@@ -10,9 +10,10 @@
 
 use core::prelude::*;
 
-use thread::Thread;
 use cell::RefCell;
 use string::String;
+use thread::Thread;
+use thread_local::State;
 
 struct ThreadInfo {
     // This field holds the known bounds of the stack in (lo, hi)
@@ -27,7 +28,7 @@ thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(N
 
 impl ThreadInfo {
     fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
-        if THREAD_INFO.destroyed() {
+        if THREAD_INFO.state() == State::Destroyed {
             panic!("Use of std::thread::Thread::current() is not possible after \
                     the thread's local data has been destroyed");
         }
diff --git a/src/libstd/sys/common/thread_local.rs b/src/libstd/sys/common/thread_local.rs
index fe7a7d8d037..9d7188a37bc 100644
--- a/src/libstd/sys/common/thread_local.rs
+++ b/src/libstd/sys/common/thread_local.rs
@@ -56,7 +56,7 @@
 
 #![allow(non_camel_case_types)]
 
-use prelude::*;
+use prelude::v1::*;
 
 use sync::atomic::{mod, AtomicUint};
 use sync::{Mutex, Once, ONCE_INIT};
@@ -137,7 +137,7 @@ pub const INIT: StaticKey = StaticKey {
 ///
 /// This value allows specific configuration of the destructor for a TLS key.
 pub const INIT_INNER: StaticKeyInner = StaticKeyInner {
-    key: atomic::INIT_ATOMIC_UINT,
+    key: atomic::ATOMIC_UINT_INIT,
 };
 
 static INIT_KEYS: Once = ONCE_INIT;
@@ -246,7 +246,7 @@ impl Drop for Key {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
     use super::{Key, StaticKey, INIT_INNER};
 
     fn assert_sync<T: Sync>() {}
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 8de4ffa7022..e3e0b279c12 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -10,16 +10,15 @@
 
 //! Blocking posix-based file I/O
 
-use libc::{mod, c_int, c_void};
-use c_str::CString;
-use mem;
-use io;
-
-use prelude::*;
+use prelude::v1::*;
 
+use c_str::{CString, ToCStr};
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
 use io::{IoResult, FileStat, SeekStyle};
 use io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
+use io;
+use libc::{mod, c_int, c_void};
+use mem;
 use sys::retry;
 use sys_common::{keep_going, eof, mkerr_libc};
 
@@ -360,7 +359,7 @@ mod tests {
     use super::FileDesc;
     use libc;
     use os;
-    use prelude::*;
+    use prelude::v1::*;
 
     #[cfg_attr(target_os = "freebsd", ignore)] // hmm, maybe pipes have a tiny buffer
     #[test]
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index c82dacf1e44..4199cbc1bb9 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -19,7 +19,7 @@ extern crate libc;
 
 use num;
 use num::{Int, SignedInt};
-use prelude::*;
+use prelude::v1::*;
 use io::{mod, IoResult, IoError};
 use sys_common::mkerr_libc;
 
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 595191db3b2..6a8f55e79c8 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -10,17 +10,18 @@
 
 //! Implementation of `std::os` functionality for unix systems
 
-use prelude::*;
+use prelude::v1::*;
 
+use c_str::ToCStr;
 use error::{FromError, Error};
 use fmt;
 use io::{IoError, IoResult};
 use libc::{mod, c_int, c_char, c_void};
-use path::BytesContainer;
+use os;
+use path::{BytesContainer};
 use ptr;
-use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
+use sync::atomic::{AtomicInt, SeqCst};
 use sys::fs::FileDesc;
-use os;
 
 use os::TMPBUF_SZ;
 
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 868b460aa5e..623f3f6a89c 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use alloc::arc::Arc;
+use prelude::v1::*;
+
 use libc;
 use c_str::CString;
 use mem;
-use sync::{atomic, Mutex};
+use sync::{atomic, Arc, Mutex};
 use io::{mod, IoResult, IoError};
-use prelude::*;
 
 use sys::{mod, timer, retry, c, set_nonblocking, wouldblock};
 use sys::fs::{fd_t, FileDesc};
@@ -117,9 +117,6 @@ pub struct UnixStream {
     write_deadline: u64,
 }
 
-unsafe impl Send for UnixStream {}
-unsafe impl Sync for UnixStream {}
-
 impl UnixStream {
     pub fn connect(addr: &CString,
                    timeout: Option<u64>) -> IoResult<UnixStream> {
@@ -218,6 +215,7 @@ pub struct UnixListener {
     path: CString,
 }
 
+// we currently own the CString, so these impls should be safe
 unsafe impl Send for UnixListener {}
 unsafe impl Sync for UnixListener {}
 
@@ -265,9 +263,6 @@ struct AcceptorInner {
     closed: atomic::AtomicBool,
 }
 
-unsafe impl Send for AcceptorInner {}
-unsafe impl Sync for AcceptorInner {}
-
 impl UnixAcceptor {
     pub fn fd(&self) -> fd_t { self.inner.listener.fd() }
 
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index c1c28bd5fc4..af09bf4fbd0 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -7,22 +7,23 @@
 // <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::v1::*;
 use self::Req::*;
 
-use libc::{mod, pid_t, c_void, c_int};
-use c_str::CString;
+use c_str::{CString, ToCStr};
+use collections;
+use hash::Hash;
+use io::process::{ProcessExit, ExitStatus, ExitSignal};
 use io::{mod, IoResult, IoError, EndOfFile};
+use libc::{mod, pid_t, c_void, c_int};
 use mem;
 use os;
-use ptr;
-use prelude::*;
-use io::process::{ProcessExit, ExitStatus, ExitSignal};
-use collections;
 use path::BytesContainer;
-use hash::Hash;
-
-use sys::{mod, retry, c, wouldblock, set_nonblocking, ms_to_timeval};
+use ptr;
+use sync::mpsc::{channel, Sender, Receiver};
 use sys::fs::FileDesc;
+use sys::{mod, retry, c, wouldblock, set_nonblocking, ms_to_timeval};
 use sys_common::helper_thread::Helper;
 use sys_common::{AsInner, mkerr_libc, timeout};
 
@@ -276,8 +277,8 @@ impl Process {
     }
 
     pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
-        use std::cmp;
-        use std::comm;
+        use cmp;
+        use sync::mpsc::TryRecvError;
 
         static mut WRITE_FD: libc::c_int = 0;
 
@@ -336,9 +337,9 @@ impl Process {
 
         let (tx, rx) = channel();
         unsafe { HELPER.send(NewChild(self.pid, tx, deadline)); }
-        return match rx.recv_opt() {
+        return match rx.recv() {
             Ok(e) => Ok(e),
-            Err(()) => Err(timeout("wait timed out")),
+            Err(..) => Err(timeout("wait timed out")),
         };
 
         // Register a new SIGCHLD handler, returning the reading half of the
@@ -419,11 +420,11 @@ impl Process {
                             Ok(NewChild(pid, tx, deadline)) => {
                                 active.push((pid, tx, deadline));
                             }
-                            Err(comm::Disconnected) => {
+                            Err(TryRecvError::Disconnected) => {
                                 assert!(active.len() == 0);
                                 break 'outer;
                             }
-                            Err(comm::Empty) => break,
+                            Err(TryRecvError::Empty) => break,
                         }
                     }
                 }
@@ -459,7 +460,7 @@ impl Process {
                     active.retain(|&(pid, ref tx, _)| {
                         let pr = Process { pid: pid };
                         match pr.try_wait() {
-                            Some(msg) => { tx.send(msg); false }
+                            Some(msg) => { tx.send(msg).unwrap(); false }
                             None => true,
                         }
                     });
diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs
index e2a78947e16..13ccf685fd7 100644
--- a/src/libstd/sys/unix/tcp.rs
+++ b/src/libstd/sys/unix/tcp.rs
@@ -8,12 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use io::net::ip;
 use io::IoResult;
 use libc;
 use mem;
 use ptr;
-use prelude::*;
 use super::{last_error, last_net_error, retry, sock_t};
 use sync::{Arc, atomic};
 use sys::fs::FileDesc;
diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local.rs
index b300e93eeb6..e507377a8fc 100644
--- a/src/libstd/sys/unix/thread_local.rs
+++ b/src/libstd/sys/unix/thread_local.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 use libc::c_int;
 
 pub type Key = pthread_key_t;
diff --git a/src/libstd/sys/unix/timer.rs b/src/libstd/sys/unix/timer.rs
index c0ef89666c0..80f93dd2f61 100644
--- a/src/libstd/sys/unix/timer.rs
+++ b/src/libstd/sys/unix/timer.rs
@@ -46,19 +46,19 @@
 //!
 //! Note that all time units in this file are in *milliseconds*.
 
+use prelude::v1::*;
 use self::Req::*;
 
+use io::IoResult;
 use libc;
 use mem;
 use os;
 use ptr;
 use sync::atomic;
-use comm;
+use sync::mpsc::{channel, Sender, Receiver, TryRecvError};
 use sys::c;
 use sys::fs::FileDesc;
 use sys_common::helper_thread::Helper;
-use prelude::*;
-use io::IoResult;
 
 helper_init! { static HELPER: Helper<Req> }
 
@@ -168,7 +168,7 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
             1 => {
                 loop {
                     match messages.try_recv() {
-                        Err(comm::Disconnected) => {
+                        Err(TryRecvError::Disconnected) => {
                             assert!(active.len() == 0);
                             break 'outer;
                         }
@@ -179,7 +179,7 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
                             match dead.iter().position(|&(i, _)| id == i) {
                                 Some(i) => {
                                     let (_, i) = dead.remove(i);
-                                    ack.send(i);
+                                    ack.send(i).unwrap();
                                     continue
                                 }
                                 None => {}
@@ -187,7 +187,7 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
                             let i = active.iter().position(|i| i.id == id);
                             let i = i.expect("no timer found");
                             let t = active.remove(i);
-                            ack.send(t);
+                            ack.send(t).unwrap();
                         }
                         Err(..) => break
                     }
@@ -211,7 +211,7 @@ impl Timer {
         // instead of ()
         HELPER.boot(|| {}, helper);
 
-        static ID: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+        static ID: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
         let id = ID.fetch_add(1, atomic::Relaxed);
         Ok(Timer {
             id: id,
@@ -271,7 +271,7 @@ impl Timer {
             None => {
                 let (tx, rx) = channel();
                 HELPER.send(RemoveTimer(self.id, tx));
-                rx.recv()
+                rx.recv().unwrap()
             }
         }
     }
diff --git a/src/libstd/sys/unix/tty.rs b/src/libstd/sys/unix/tty.rs
index 28c17fd4966..4ef687d41d8 100644
--- a/src/libstd/sys/unix/tty.rs
+++ b/src/libstd/sys/unix/tty.rs
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use sys::fs::FileDesc;
-use prelude::*;
 use libc::{mod, c_int};
 use io::{mod, IoResult, IoError};
 use sys_common;
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 6cccefbe890..1ee57434fb9 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -15,7 +15,7 @@
 #![allow(non_camel_case_types)]
 
 use libc;
-use prelude::*;
+use prelude::v1::*;
 
 pub const WSADESCRIPTION_LEN: uint = 256;
 pub const WSASYS_STATUS_LEN: uint = 128;
@@ -132,7 +132,8 @@ extern "system" {
 pub mod compat {
     use intrinsics::{atomic_store_relaxed, transmute};
     use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
-    use prelude::*;
+    use prelude::v1::*;
+    use c_str::ToCStr;
 
     extern "system" {
         fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 3ad439078b9..523d60c71aa 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -21,7 +21,7 @@ use ptr;
 use str;
 use io;
 
-use prelude::*;
+use prelude::v1::*;
 use sys;
 use sys::os;
 use sys_common::{keep_going, eof, mkerr_libc};
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 57c284ed6a3..1034f0615d9 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -18,9 +18,10 @@
 
 extern crate libc;
 
+use prelude::v1::*;
+
 use num;
 use mem;
-use prelude::*;
 use io::{mod, IoResult, IoError};
 use sync::{Once, ONCE_INIT};
 
@@ -28,7 +29,7 @@ macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
     static $name: Helper<$m> = Helper {
         lock: ::sync::MUTEX_INIT,
         cond: ::sync::CONDVAR_INIT,
-        chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
+        chan: ::cell::UnsafeCell { value: 0 as *mut ::sync::mpsc::Sender<$m> },
         signal: ::cell::UnsafeCell { value: 0 },
         initialized: ::cell::UnsafeCell { value: false },
         shutdown: ::cell::UnsafeCell { value: false },
@@ -171,7 +172,7 @@ pub fn init_net() {
     unsafe {
         static START: Once = ONCE_INIT;
 
-        START.doit(|| {
+        START.call_once(|| {
             let mut data: c::WSADATA = mem::zeroed();
             let ret = c::WSAStartup(0x202, // version 2.2
                                     &mut data);
diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs
index 3ac7c09154e..e0fa02b5599 100644
--- a/src/libstd/sys/windows/mutex.rs
+++ b/src/libstd/sys/windows/mutex.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 
 use sync::atomic;
 use alloc::{mod, heap};
@@ -20,7 +20,7 @@ const SPIN_COUNT: DWORD = 4000;
 
 pub struct Mutex { inner: atomic::AtomicUint }
 
-pub const MUTEX_INIT: Mutex = Mutex { inner: atomic::INIT_ATOMIC_UINT };
+pub const MUTEX_INIT: Mutex = Mutex { inner: atomic::ATOMIC_UINT_INIT };
 
 unsafe impl Sync for Mutex {}
 
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 09003f87ff0..dfdee0e0385 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -13,7 +13,7 @@
 // FIXME: move various extern bindings from here into liblibc or
 // something similar
 
-use prelude::*;
+use prelude::v1::*;
 
 use fmt;
 use io::{IoResult, IoError};
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index fc3640f2604..f173d5fc6d4 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -84,14 +84,14 @@
 //! the test suite passing (the suite is in libstd), and that's good enough for
 //! me!
 
-use alloc::arc::Arc;
+use prelude::v1::*;
+
 use libc;
 use c_str::CString;
 use mem;
 use ptr;
-use sync::{atomic, Mutex};
+use sync::{atomic, Arc, Mutex};
 use io::{mod, IoError, IoResult};
-use prelude::*;
 
 use sys_common::{mod, eof};
 
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index b03c62395d1..cb99a886ce4 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -8,14 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use libc::{pid_t, c_void, c_int};
 use libc;
-use c_str::CString;
+use c_str::{CString, ToCStr};
 use io;
 use mem;
 use os;
 use ptr;
-use prelude::*;
 use io::process::{ProcessExit, ExitStatus, ExitSignal};
 use collections;
 use path::BytesContainer;
@@ -466,10 +467,11 @@ fn free_handle(handle: *mut ()) {
 
 #[cfg(test)]
 mod tests {
+    use c_str::ToCStr;
 
     #[test]
     fn test_make_command_line() {
-        use prelude::*;
+        use prelude::v1::*;
         use str;
         use c_str::CString;
         use super::make_command_line;
diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs
index 513c1d38e36..5a929f6b2b5 100644
--- a/src/libstd/sys/windows/tcp.rs
+++ b/src/libstd/sys/windows/tcp.rs
@@ -13,7 +13,7 @@ use io::IoResult;
 use libc;
 use mem;
 use ptr;
-use prelude::*;
+use prelude::v1::*;
 use super::{last_error, last_net_error, retry, sock_t};
 use sync::{Arc, atomic};
 use sys::fs::FileDesc;
diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs
index 60b0d584db3..b96e26c7a86 100644
--- a/src/libstd/sys/windows/thread_local.rs
+++ b/src/libstd/sys/windows/thread_local.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 
 use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
 
diff --git a/src/libstd/sys/windows/timer.rs b/src/libstd/sys/windows/timer.rs
index 874838950cd..343b78543bf 100644
--- a/src/libstd/sys/windows/timer.rs
+++ b/src/libstd/sys/windows/timer.rs
@@ -21,16 +21,16 @@
 //! the other two implementations of timers with nothing *that* new showing up.
 
 use self::Req::*;
+use prelude::v1::*;
 
 use libc;
 use ptr;
-use comm;
 
+use io::IoResult;
+use sync::mpsc::{channel, Sender, Receiver, TryRecvError};
 use sys::c;
 use sys::fs::FileDesc;
 use sys_common::helper_thread::Helper;
-use prelude::*;
-use io::IoResult;
 
 helper_init! { static HELPER: Helper<Req> }
 
@@ -71,7 +71,7 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
                         chans.push((c, one));
                     }
                     Ok(RemoveTimer(obj, c)) => {
-                        c.send(());
+                        c.send(()).unwrap();
                         match objs.iter().position(|&o| o == obj) {
                             Some(i) => {
                                 drop(objs.remove(i));
@@ -80,7 +80,7 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
                             None => {}
                         }
                     }
-                    Err(comm::Disconnected) => {
+                    Err(TryRecvError::Disconnected) => {
                         assert_eq!(objs.len(), 1);
                         assert_eq!(chans.len(), 0);
                         break 'outer;
@@ -132,7 +132,7 @@ impl Timer {
 
         let (tx, rx) = channel();
         HELPER.send(RemoveTimer(self.obj, tx));
-        rx.recv();
+        rx.recv().unwrap();
 
         self.on_worker = false;
     }
diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs
index a88d11eed22..7591025d76d 100644
--- a/src/libstd/sys/windows/tty.rs
+++ b/src/libstd/sys/windows/tty.rs
@@ -25,19 +25,20 @@
 //! wrapper that performs encoding/decoding, this implementation should switch
 //! to working in raw UTF-16, with such a wrapper around it.
 
-use super::c::{ReadConsoleW, WriteConsoleW, GetConsoleMode, SetConsoleMode};
-use super::c::{ERROR_ILLEGAL_CHARACTER};
-use super::c::{ENABLE_ECHO_INPUT, ENABLE_EXTENDED_FLAGS};
-use super::c::{ENABLE_INSERT_MODE, ENABLE_LINE_INPUT};
-use super::c::{ENABLE_PROCESSED_INPUT, ENABLE_QUICK_EDIT_MODE};
-use libc::{c_int, HANDLE, LPDWORD, DWORD, LPVOID};
-use libc::{get_osfhandle, CloseHandle};
-use libc::types::os::arch::extra::LPCVOID;
+use prelude::v1::*;
+
 use io::{mod, IoError, IoResult, MemReader};
 use iter::repeat;
-use prelude::*;
+use libc::types::os::arch::extra::LPCVOID;
+use libc::{c_int, HANDLE, LPDWORD, DWORD, LPVOID};
+use libc::{get_osfhandle, CloseHandle};
 use ptr;
 use str::from_utf8;
+use super::c::{ENABLE_ECHO_INPUT, ENABLE_EXTENDED_FLAGS};
+use super::c::{ENABLE_INSERT_MODE, ENABLE_LINE_INPUT};
+use super::c::{ENABLE_PROCESSED_INPUT, ENABLE_QUICK_EDIT_MODE};
+use super::c::{ERROR_ILLEGAL_CHARACTER};
+use super::c::{ReadConsoleW, WriteConsoleW, GetConsoleMode, SetConsoleMode};
 
 fn invalid_encoding() -> IoError {
     IoError {
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index a7b3ee996a3..3c87309dabc 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -440,13 +440,15 @@ impl<T: Send> Drop for JoinGuard<T> {
 
 #[cfg(test)]
 mod test {
-    use prelude::*;
+    use prelude::v1::*;
+
     use any::{Any, AnyRefExt};
+    use sync::mpsc::{channel, Sender};
     use boxed::BoxAny;
     use result;
     use std::io::{ChanReader, ChanWriter};
-    use thunk::Thunk;
     use super::{Thread, Builder};
+    use thunk::Thunk;
 
     // !!! These tests are dangerous. If something is buggy, they will hang, !!!
     // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
@@ -469,9 +471,9 @@ mod test {
     fn test_run_basic() {
         let (tx, rx) = channel();
         Thread::spawn(move|| {
-            tx.send(());
+            tx.send(()).unwrap();
         }).detach();
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -504,7 +506,7 @@ mod test {
             let tx = tx.clone();
             Thread::spawn(move|| {
                 if i == 0 {
-                    tx.send(());
+                    tx.send(()).unwrap();
                 } else {
                     f(i - 1, tx);
                 }
@@ -512,7 +514,7 @@ mod test {
 
         }
         f(10, tx);
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -521,11 +523,11 @@ mod test {
 
         Thread::spawn(move|| {
             Thread::spawn(move|| {
-                tx.send(());
+                tx.send(()).unwrap();
             }).detach();
         }).detach();
 
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk) {
@@ -536,10 +538,10 @@ mod test {
 
         spawnfn(Thunk::new(move|| {
             let x_in_child = (&*x) as *const int as uint;
-            tx.send(x_in_child);
+            tx.send(x_in_child).unwrap();
         }));
 
-        let x_in_child = rx.recv();
+        let x_in_child = rx.recv().unwrap();
         assert_eq!(x_in_parent, x_in_child);
     }
 
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 14dd2a1ac9b..75e5ac59685 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -35,20 +35,23 @@
 //! `Cell` or `RefCell` types.
 
 #![macro_escape]
-#![experimental]
+#![stable]
 
-use prelude::*;
+use prelude::v1::*;
 
 use cell::UnsafeCell;
 
-// Sure wish we had macro hygiene, no?
-#[doc(hidden)] pub use self::imp::Key as KeyInner;
-#[doc(hidden)] pub use self::imp::destroy_value;
-#[doc(hidden)] pub use sys_common::thread_local::INIT_INNER as OS_INIT_INNER;
-#[doc(hidden)] pub use sys_common::thread_local::StaticKey as OsStaticKey;
-
 pub mod scoped;
 
+// Sure wish we had macro hygiene, no?
+#[doc(hidden)]
+pub mod __impl {
+    pub use super::imp::Key as KeyInner;
+    pub use super::imp::destroy_value;
+    pub use sys_common::thread_local::INIT_INNER as OS_INIT_INNER;
+    pub use sys_common::thread_local::StaticKey as OsStaticKey;
+}
+
 /// A thread local storage key which owns its contents.
 ///
 /// This key uses the fastest possible implementation available to it for the
@@ -90,6 +93,7 @@ pub mod scoped;
 ///     assert_eq!(*f.borrow(), 2);
 /// });
 /// ```
+#[stable]
 pub struct Key<T> {
     // The key itself may be tagged with #[thread_local], and this `Key` is
     // stored as a `static`, and it's not valid for a static to reference the
@@ -100,7 +104,7 @@ pub struct Key<T> {
     // This is trivially devirtualizable by LLVM because we never store anything
     // to this field and rustc can declare the `static` as constant as well.
     #[doc(hidden)]
-    pub inner: fn() -> &'static KeyInner<UnsafeCell<Option<T>>>,
+    pub inner: fn() -> &'static __impl::KeyInner<UnsafeCell<Option<T>>>,
 
     // initialization routine to invoke to create a value
     #[doc(hidden)]
@@ -109,12 +113,12 @@ pub struct Key<T> {
 
 /// Declare a new thread local storage key of type `std::thread_local::Key`.
 #[macro_export]
-#[doc(hidden)]
+#[stable]
 macro_rules! thread_local {
     (static $name:ident: $t:ty = $init:expr) => (
         static $name: ::std::thread_local::Key<$t> = {
             use std::cell::UnsafeCell as __UnsafeCell;
-            use std::thread_local::KeyInner as __KeyInner;
+            use std::thread_local::__impl::KeyInner as __KeyInner;
             use std::option::Option as __Option;
             use std::option::Option::None as __None;
 
@@ -131,7 +135,7 @@ macro_rules! thread_local {
     (pub static $name:ident: $t:ty = $init:expr) => (
         pub static $name: ::std::thread_local::Key<$t> = {
             use std::cell::UnsafeCell as __UnsafeCell;
-            use std::thread_local::KeyInner as __KeyInner;
+            use std::thread_local::__impl::KeyInner as __KeyInner;
             use std::option::Option as __Option;
             use std::option::Option::None as __None;
 
@@ -168,21 +172,22 @@ macro_rules! thread_local {
 // itself. Woohoo.
 
 #[macro_export]
+#[doc(hidden)]
 macro_rules! __thread_local_inner {
     (static $name:ident: $t:ty = $init:expr) => (
         #[cfg_attr(any(target_os = "macos", target_os = "linux"), thread_local)]
-        static $name: ::std::thread_local::KeyInner<$t> =
+        static $name: ::std::thread_local::__impl::KeyInner<$t> =
             __thread_local_inner!($init, $t);
     );
     (pub static $name:ident: $t:ty = $init:expr) => (
         #[cfg_attr(any(target_os = "macos", target_os = "linux"), thread_local)]
-        pub static $name: ::std::thread_local::KeyInner<$t> =
+        pub static $name: ::std::thread_local::__impl::KeyInner<$t> =
             __thread_local_inner!($init, $t);
     );
     ($init:expr, $t:ty) => ({
         #[cfg(any(target_os = "macos", target_os = "linux"))]
-        const INIT: ::std::thread_local::KeyInner<$t> = {
-            ::std::thread_local::KeyInner {
+        const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
+            ::std::thread_local::__impl::KeyInner {
                 inner: ::std::cell::UnsafeCell { value: $init },
                 dtor_registered: ::std::cell::UnsafeCell { value: false },
                 dtor_running: ::std::cell::UnsafeCell { value: false },
@@ -190,24 +195,54 @@ macro_rules! __thread_local_inner {
         };
 
         #[cfg(all(not(any(target_os = "macos", target_os = "linux"))))]
-        const INIT: ::std::thread_local::KeyInner<$t> = {
+        const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
             unsafe extern fn __destroy(ptr: *mut u8) {
-                ::std::thread_local::destroy_value::<$t>(ptr);
+                ::std::thread_local::__impl::destroy_value::<$t>(ptr);
             }
 
-            ::std::thread_local::KeyInner {
+            ::std::thread_local::__impl::KeyInner {
                 inner: ::std::cell::UnsafeCell { value: $init },
-                os: ::std::thread_local::OsStaticKey {
-                    inner: ::std::thread_local::OS_INIT_INNER,
+                os: ::std::thread_local::__impl::OsStaticKey {
+                    inner: ::std::thread_local::__impl::OS_INIT_INNER,
                     dtor: ::std::option::Option::Some(__destroy as unsafe extern fn(*mut u8)),
                 },
             }
         };
 
-        INIT
+        _INIT
     });
 }
 
+/// Indicator of the state of a thread local storage key.
+#[unstable = "state querying was recently added"]
+#[deriving(Eq, PartialEq, Copy)]
+pub enum State {
+    /// All keys are in this state whenever a thread starts. Keys will
+    /// transition to the `Valid` state once the first call to `with` happens
+    /// and the initialization expression succeeds.
+    ///
+    /// Keys in the `Uninitialized` state will yield a reference to the closure
+    /// passed to `with` so long as the initialization routine does not panic.
+    Uninitialized,
+
+    /// Once a key has been accessed successfully, it will enter the `Valid`
+    /// state. Keys in the `Valid` state will remain so until the thread exits,
+    /// at which point the destructor will be run and the key will enter the
+    /// `Destroyed` state.
+    ///
+    /// Keys in the `Valid` state will be guaranteed to yield a reference to the
+    /// closure passed to `with`.
+    Valid,
+
+    /// When a thread exits, the destructors for keys will be run (if
+    /// necessary). While a destructor is running, and possibly after a
+    /// destructor has run, a key is in the `Destroyed` state.
+    ///
+    /// Keys in the `Destroyed` states will trigger a panic when accessed via
+    /// `with`.
+    Destroyed,
+}
+
 impl<T: 'static> Key<T> {
     /// Acquire a reference to the value in this TLS key.
     ///
@@ -219,6 +254,7 @@ impl<T: 'static> Key<T> {
     /// This function will `panic!()` if the key currently has its
     /// destructor running, and it **may** panic if the destructor has
     /// previously been run for this thread.
+    #[stable]
     pub fn with<F, R>(&'static self, f: F) -> R
                       where F: FnOnce(&T) -> R {
         let slot = (self.inner)();
@@ -233,22 +269,57 @@ impl<T: 'static> Key<T> {
     }
 
     unsafe fn init(&self, slot: &UnsafeCell<Option<T>>) -> &T {
-        *slot.get() = Some((self.init)());
-        (*slot.get()).as_ref().unwrap()
+        // Execute the initialization up front, *then* move it into our slot,
+        // just in case initialization fails.
+        let value = (self.init)();
+        let ptr = slot.get();
+        *ptr = Some(value);
+        (*ptr).as_ref().unwrap()
     }
 
-    /// Test this TLS key to determine whether its value has been destroyed for
-    /// the current thread or not.
+    /// Query the current state of this key.
+    ///
+    /// A key is initially in the `Uninitialized` state whenever a thread
+    /// starts. It will remain in this state up until the first call to `with`
+    /// within a thread has run the initialization expression successfully.
+    ///
+    /// Once the initialization expression succeeds, the key transitions to the
+    /// `Valid` state which will guarantee that future calls to `with` will
+    /// succeed within the thread.
     ///
-    /// This will not initialize the key if it is not already initialized.
-    pub fn destroyed(&'static self) -> bool {
-        unsafe { (self.inner)().get().is_none() }
+    /// When a thread exits, each key will be destroyed in turn, and as keys are
+    /// destroyed they will enter the `Destroyed` state just before the
+    /// destructor starts to run. Keys may remain in the `Destroyed` state after
+    /// destruction has completed. Keys without destructors (e.g. with types
+    /// that are `Copy`), may never enter the `Destroyed` state.
+    ///
+    /// Keys in the `Uninitialized` can be accessed so long as the
+    /// initialization does not panic. Keys in the `Valid` state are guaranteed
+    /// to be able to be accessed. Keys in the `Destroyed` state will panic on
+    /// any call to `with`.
+    #[unstable = "state querying was recently added"]
+    pub fn state(&'static self) -> State {
+        unsafe {
+            match (self.inner)().get() {
+                Some(cell) => {
+                    match *cell.get() {
+                        Some(..) => State::Valid,
+                        None => State::Uninitialized,
+                    }
+                }
+                None => State::Destroyed,
+            }
+        }
     }
+
+    /// Deprecated
+    #[deprecated = "function renamed to state() and returns more info"]
+    pub fn destroyed(&'static self) -> bool { self.state() == State::Destroyed }
 }
 
 #[cfg(any(target_os = "macos", target_os = "linux"))]
 mod imp {
-    use prelude::*;
+    use prelude::v1::*;
 
     use cell::UnsafeCell;
     use intrinsics;
@@ -380,7 +451,7 @@ mod imp {
 
 #[cfg(not(any(target_os = "macos", target_os = "linux")))]
 mod imp {
-    use prelude::*;
+    use prelude::v1::*;
 
     use cell::UnsafeCell;
     use mem;
@@ -453,9 +524,11 @@ mod imp {
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
+    use prelude::v1::*;
 
+    use sync::mpsc::{channel, Sender};
     use cell::UnsafeCell;
+    use super::State;
     use thread::Thread;
 
     struct Foo(Sender<()>);
@@ -463,7 +536,7 @@ mod tests {
     impl Drop for Foo {
         fn drop(&mut self) {
             let Foo(ref s) = *self;
-            s.send(());
+            s.send(()).unwrap();
         }
     }
 
@@ -476,13 +549,13 @@ mod tests {
             *f.get() = 2;
         });
         let (tx, rx) = channel();
-        spawn(move|| {
+        let _t = Thread::spawn(move|| {
             FOO.with(|f| unsafe {
                 assert_eq!(*f.get(), 1);
             });
-            tx.send(());
+            tx.send(()).unwrap();
         });
-        rx.recv();
+        rx.recv().unwrap();
 
         FOO.with(|f| unsafe {
             assert_eq!(*f.get(), 2);
@@ -490,19 +563,42 @@ mod tests {
     }
 
     #[test]
+    fn states() {
+        struct Foo;
+        impl Drop for Foo {
+            fn drop(&mut self) {
+                assert!(FOO.state() == State::Destroyed);
+            }
+        }
+        fn foo() -> Foo {
+            assert!(FOO.state() == State::Uninitialized);
+            Foo
+        }
+        thread_local!(static FOO: Foo = foo());
+
+        Thread::spawn(|| {
+            assert!(FOO.state() == State::Uninitialized);
+            FOO.with(|_| {
+                assert!(FOO.state() == State::Valid);
+            });
+            assert!(FOO.state() == State::Valid);
+        }).join().ok().unwrap();
+    }
+
+    #[test]
     fn smoke_dtor() {
         thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell {
             value: None
         });
 
         let (tx, rx) = channel();
-        spawn(move|| unsafe {
+        let _t = Thread::spawn(move|| unsafe {
             let mut tx = Some(tx);
             FOO.with(|f| {
                 *f.get() = Some(Foo(tx.take().unwrap()));
             });
         });
-        rx.recv();
+        rx.recv().unwrap();
     }
 
     #[test]
@@ -521,7 +617,7 @@ mod tests {
             fn drop(&mut self) {
                 unsafe {
                     HITS += 1;
-                    if K2.destroyed() {
+                    if K2.state() == State::Destroyed {
                         assert_eq!(HITS, 3);
                     } else {
                         if HITS == 1 {
@@ -537,7 +633,7 @@ mod tests {
             fn drop(&mut self) {
                 unsafe {
                     HITS += 1;
-                    assert!(!K1.destroyed());
+                    assert!(K1.state() != State::Destroyed);
                     assert_eq!(HITS, 2);
                     K1.with(|s| *s.get() = Some(S1));
                 }
@@ -546,7 +642,7 @@ mod tests {
 
         Thread::spawn(move|| {
             drop(S1);
-        }).join();
+        }).join().ok().unwrap();
     }
 
     #[test]
@@ -558,13 +654,13 @@ mod tests {
 
         impl Drop for S1 {
             fn drop(&mut self) {
-                assert!(K1.destroyed());
+                assert!(K1.state() == State::Destroyed);
             }
         }
 
         Thread::spawn(move|| unsafe {
             K1.with(|s| *s.get() = Some(S1));
-        }).join();
+        }).join().ok().unwrap();
     }
 
     #[test]
@@ -581,7 +677,7 @@ mod tests {
             fn drop(&mut self) {
                 let S1(ref tx) = *self;
                 unsafe {
-                    if !K2.destroyed() {
+                    if K2.state() != State::Destroyed {
                         K2.with(|s| *s.get() = Some(Foo(tx.clone())));
                     }
                 }
@@ -589,17 +685,17 @@ mod tests {
         }
 
         let (tx, rx) = channel();
-        spawn(move|| unsafe {
+        let _t = Thread::spawn(move|| unsafe {
             let mut tx = Some(tx);
             K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
         });
-        rx.recv();
+        rx.recv().unwrap();
     }
 }
 
 #[cfg(test)]
 mod dynamic_tests {
-    use prelude::*;
+    use prelude::v1::*;
 
     use cell::RefCell;
     use collections::HashMap;
diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs
index 5f96548c053..c53d393f1eb 100644
--- a/src/libstd/thread_local/scoped.rs
+++ b/src/libstd/thread_local/scoped.rs
@@ -39,12 +39,17 @@
 //! ```
 
 #![macro_escape]
+#![unstable = "scoped TLS has yet to have wide enough use to fully consider \
+               stabilizing its interface"]
 
-use prelude::*;
+use prelude::v1::*;
 
 // macro hygiene sure would be nice, wouldn't it?
-#[doc(hidden)] pub use self::imp::KeyInner;
-#[doc(hidden)] pub use sys_common::thread_local::INIT as OS_INIT;
+#[doc(hidden)]
+pub mod __impl {
+    pub use super::imp::KeyInner;
+    pub use sys_common::thread_local::INIT as OS_INIT;
+}
 
 /// Type representing a thread local storage key corresponding to a reference
 /// to the type parameter `T`.
@@ -53,7 +58,7 @@ use prelude::*;
 /// type `T` scoped to a particular lifetime. Keys provides two methods, `set`
 /// and `with`, both of which currently use closures to control the scope of
 /// their contents.
-pub struct Key<T> { #[doc(hidden)] pub inner: KeyInner<T> }
+pub struct Key<T> { #[doc(hidden)] pub inner: __impl::KeyInner<T> }
 
 /// Declare a new scoped thread local storage key.
 ///
@@ -88,21 +93,21 @@ macro_rules! __scoped_thread_local_inner {
         use std::thread_local::scoped::Key as __Key;
 
         #[cfg(not(any(windows, target_os = "android", target_os = "ios")))]
-        const INIT: __Key<$t> = __Key {
-            inner: ::std::thread_local::scoped::KeyInner {
+        const _INIT: __Key<$t> = __Key {
+            inner: ::std::thread_local::scoped::__impl::KeyInner {
                 inner: ::std::cell::UnsafeCell { value: 0 as *mut _ },
             }
         };
 
         #[cfg(any(windows, target_os = "android", target_os = "ios"))]
-        const INIT: __Key<$t> = __Key {
-            inner: ::std::thread_local::scoped::KeyInner {
-                inner: ::std::thread_local::scoped::OS_INIT,
+        const _INIT: __Key<$t> = __Key {
+            inner: ::std::thread_local::scoped::__impl::KeyInner {
+                inner: ::std::thread_local::scoped::__impl::OS_INIT,
                 marker: ::std::kinds::marker::InvariantType,
             }
         };
 
-        INIT
+        _INIT
     })
 }
 
@@ -139,7 +144,7 @@ impl<T> Key<T> {
         F: FnOnce() -> R,
     {
         struct Reset<'a, T: 'a> {
-            key: &'a KeyInner<T>,
+            key: &'a __impl::KeyInner<T>,
             val: *mut T,
         }
         #[unsafe_destructor]
@@ -238,7 +243,7 @@ mod imp {
 #[cfg(test)]
 mod tests {
     use cell::Cell;
-    use prelude::*;
+    use prelude::v1::*;
 
     scoped_thread_local!(static FOO: uint);
 
diff --git a/src/libstd/time/mod.rs b/src/libstd/time/mod.rs
index 7bc15798a4f..d6c94f27a8b 100644
--- a/src/libstd/time/mod.rs
+++ b/src/libstd/time/mod.rs
@@ -45,7 +45,7 @@ fn precise_time_ns() -> u64 {
                                                                                    denom: 0 };
         static ONCE: sync::Once = sync::ONCE_INIT;
         unsafe {
-            ONCE.doit(|| {
+            ONCE.call_once(|| {
                 imp::mach_timebase_info(&mut TIMEBASE);
             });
             let time = imp::mach_absolute_time();
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 5cd60d6e153..fc90bffa03c 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -35,14 +35,14 @@
 //!
 //! # Examples
 //!
-//! Using methods:
+//! Using fields:
 //!
 //! ```
 //! #[allow(deprecated)]
 //! # fn main() {
 //! let pair = ("pi", 3.14f64);
-//! assert_eq!(pair.val0(), "pi");
-//! assert_eq!(pair.val1(), 3.14f64);
+//! assert_eq!(pair.0, "pi");
+//! assert_eq!(pair.1, 3.14f64);
 //! # }
 //! ```
 //!
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 12432c8c78f..a705872b53d 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -643,8 +643,8 @@ pub enum LocalSource {
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
 #[deriving(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub struct Local {
-    pub ty: P<Ty>,
     pub pat: P<Pat>,
+    pub ty: Option<P<Ty>>,
     pub init: Option<P<Expr>>,
     pub id: NodeId,
     pub span: Span,
@@ -1662,6 +1662,7 @@ mod test {
     use serialize;
     use codemap::*;
     use super::*;
+    use std::fmt;
 
     // are ASTs encodable?
     #[test]
@@ -1687,6 +1688,6 @@ mod test {
             exported_macros: Vec::new(),
         };
         // doesn't matter which encoder we use....
-        let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;
+        let _f = &e as &serialize::Encodable<json::Encoder, fmt::Error>;
     }
 }
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index e61afb8b193..5eac6546c6b 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -10,19 +10,24 @@
 //
 // ignore-lexer-test FIXME #15679
 
-//! The CodeMap tracks all the source code used within a single crate, mapping from integer byte
-//! positions to the original source code location. Each bit of source parsed during crate parsing
-//! (typically files, in-memory strings, or various bits of macro expansion) cover a continuous
-//! range of bytes in the CodeMap and are represented by FileMaps. Byte positions are stored in
-//! `spans` and used pervasively in the compiler. They are absolute positions within the CodeMap,
-//! which upon request can be converted to line and column information, source code snippets, etc.
+//! The CodeMap tracks all the source code used within a single crate, mapping
+//! from integer byte positions to the original source code location. Each bit
+//! of source parsed during crate parsing (typically files, in-memory strings,
+//! or various bits of macro expansion) cover a continuous range of bytes in the
+//! CodeMap and are represented by FileMaps. Byte positions are stored in
+//! `spans` and used pervasively in the compiler. They are absolute positions
+//! within the CodeMap, which upon request can be converted to line and column
+//! information, source code snippets, etc.
 
 pub use self::MacroFormat::*;
 
-use serialize::{Encodable, Decodable, Encoder, Decoder};
 use std::cell::RefCell;
+use std::num::ToPrimitive;
+use std::ops::{Add, Sub};
 use std::rc::Rc;
+
 use libc::c_uint;
+use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 pub trait Pos {
     fn from_uint(n: uint) -> Self;
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 239af188909..ea345f3a458 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -482,8 +482,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             self.pat_ident(sp, ident)
         };
         let local = P(ast::Local {
-            ty: self.ty_infer(sp),
             pat: pat,
+            ty: None,
             init: Some(ex),
             id: ast::DUMMY_NODE_ID,
             span: sp,
@@ -506,8 +506,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             self.pat_ident(sp, ident)
         };
         let local = P(ast::Local {
-            ty: typ,
             pat: pat,
+            ty: Some(typ),
             init: Some(ex),
             id: ast::DUMMY_NODE_ID,
             span: sp,
diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs
index 2844c0b523e..9f225d55b44 100644
--- a/src/libsyntax/ext/bytes.rs
+++ b/src/libsyntax/ext/bytes.rs
@@ -17,7 +17,6 @@ use ext::base;
 use ext::build::AstBuilder;
 use std::ascii::AsciiExt;
 
-
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[ast::TokenTree])
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 5de7068563d..dcf25a26e2c 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -712,7 +712,7 @@ fn expand_non_macro_stmt(Spanned {node, span: stmt_span}: Stmt, fld: &mut MacroE
                 let rewritten_local = local.map(|Local {id, pat, ty, init, source, span}| {
                     // expand the ty since TyFixedLengthVec contains an Expr
                     // and thus may have a macro use
-                    let expanded_ty = fld.fold_ty(ty);
+                    let expanded_ty = ty.map(|t| fld.fold_ty(t));
                     // expand the pat (it might contain macro uses):
                     let expanded_pat = fld.fold_pat(pat);
                     // find the PatIdents in the pattern:
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index d87960ebdb8..e46bd7ac4bc 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -50,8 +50,7 @@ pub mod rt {
 
     impl<T: ToTokens> ToTokens for Vec<T> {
         fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
-            let a = self.iter().flat_map(|t| t.to_tokens(cx).into_iter());
-            FromIterator::from_iter(a)
+            self.iter().flat_map(|t| t.to_tokens(cx).into_iter()).collect()
         }
     }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index b2c2d7eb626..545856a27af 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -56,6 +56,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
     ("simd", Active),
     ("default_type_params", Active),
     ("quote", Active),
+    ("link_llvm_intrinsics", Active),
     ("linkage", Active),
     ("struct_inherit", Removed),
 
@@ -77,8 +78,11 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
     // to bootstrap fix for #5723.
     ("issue_5723_bootstrap", Accepted),
 
-    // A way to temporary opt out of opt in copy. This will *never* be accepted.
-    ("opt_out_copy", Active),
+    // A way to temporarily opt out of opt in copy. This will *never* be accepted.
+    ("opt_out_copy", Deprecated),
+
+    // A way to temporarily opt out of the new orphan rules. This will *never* be accepted.
+    ("old_orphan_check", Deprecated),
 
     // These are used to test this portion of the compiler, they don't actually
     // mean anything
@@ -91,6 +95,10 @@ enum Status {
     /// currently being considered for addition/removal.
     Active,
 
+    /// Represents a feature gate that is temporarily enabling deprecated behavior.
+    /// This gate will never be accepted.
+    Deprecated,
+
     /// Represents a feature which has since been removed (it was once Active)
     Removed,
 
@@ -108,6 +116,7 @@ pub struct Features {
     pub visible_private_types: bool,
     pub quote: bool,
     pub opt_out_copy: bool,
+    pub old_orphan_check: bool,
 }
 
 impl Features {
@@ -120,6 +129,7 @@ impl Features {
             visible_private_types: false,
             quote: false,
             opt_out_copy: false,
+            old_orphan_check: false,
         }
     }
 }
@@ -327,6 +337,16 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                               "the `linkage` attribute is experimental \
                                and not portable across platforms")
         }
+
+        let links_to_llvm = match attr::first_attr_value_str_by_name(i.attrs[], "link_name") {
+            Some(val) => val.get().starts_with("llvm."),
+            _ => false
+        };
+        if links_to_llvm {
+            self.gate_feature("link_llvm_intrinsics", i.span,
+                              "linking to LLVM intrinsics is experimental");
+        }
+
         visit::walk_foreign_item(self, i)
     }
 
@@ -442,7 +462,16 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
                     };
                     match KNOWN_FEATURES.iter()
                                         .find(|& &(n, _)| name == n) {
-                        Some(&(name, Active)) => { cx.features.push(name); }
+                        Some(&(name, Active)) => {
+                            cx.features.push(name);
+                        }
+                        Some(&(name, Deprecated)) => {
+                            cx.features.push(name);
+                            span_handler.span_warn(
+                                mi.span,
+                                "feature is deprecated and will only be available \
+                                 for a limited time, please rewrite code that relies on it");
+                        }
                         Some(&(_, Removed)) => {
                             span_handler.span_err(mi.span, "feature has been removed");
                         }
@@ -469,6 +498,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
         visible_private_types: cx.has_feature("visible_private_types"),
         quote: cx.has_feature("quote"),
         opt_out_copy: cx.has_feature("opt_out_copy"),
+        old_orphan_check: cx.has_feature("old_orphan_check"),
     },
     unknown_features)
 }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 4f0169e31f2..3d3068f6868 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -53,7 +53,7 @@ impl<T> MoveMap<T> for OwnedSlice<T> {
     }
 }
 
-pub trait Folder {
+pub trait Folder : Sized {
     // Any additions to this trait should happen in form
     // of a call to a public `noop_*` function that only calls
     // out to the folder again, not other `noop_*` functions.
@@ -553,7 +553,7 @@ pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedPara
 pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
     l.map(|Local {id, pat, ty, init, source, span}| Local {
         id: fld.new_id(id),
-        ty: fld.fold_ty(ty),
+        ty: ty.map(|t| fld.fold_ty(t)),
         pat: fld.fold_pat(pat),
         init: init.map(|e| fld.fold_expr(e)),
         source: source,
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index d5093c5055c..18cdb3fc647 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -26,6 +26,8 @@
 #![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)]
 #![feature(quote, unsafe_destructor)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
+#![feature(associated_types)]
 
 extern crate arena;
 extern crate fmt_macros;
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 3023c547fb0..bc2e0923115 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt;
 use std::default::Default;
+use std::fmt;
+use std::iter::FromIterator;
+use std::ops::Deref;
 use std::vec;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
@@ -54,7 +56,9 @@ impl<T> OwnedSlice<T> {
     }
 }
 
-impl<T> Deref<[T]> for OwnedSlice<T> {
+impl<T> Deref for OwnedSlice<T> {
+    type Target = [T];
+
     fn deref(&self) -> &[T] {
         self.as_slice()
     }
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 13d020f6ae3..0f5ff33021c 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -16,6 +16,7 @@ use ext::tt::transcribe::tt_next_token;
 use parse::token;
 use parse::token::{str_to_ident};
 
+use std::borrow::IntoCow;
 use std::char;
 use std::fmt;
 use std::mem::replace;
@@ -358,7 +359,7 @@ impl<'a> StringReader<'a> {
 
     pub fn nextnextch(&self) -> Option<char> {
         let offset = self.byte_offset(self.pos).to_uint();
-        let s = self.filemap.deref().src[];
+        let s = self.filemap.src.as_slice();
         if offset >= s.len() { return None }
         let str::CharRange { next, .. } = s.char_range_at(offset);
         if next < s.len() {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f84ddcf360e..c597968d4ae 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -84,11 +84,12 @@ use owned_slice::OwnedSlice;
 
 use std::collections::HashSet;
 use std::io::fs::PathExtensions;
+use std::iter;
 use std::mem;
 use std::num::Float;
 use std::rc::Rc;
-use std::iter;
 use std::slice;
+use std::str::from_str;
 
 bitflags! {
     flags Restrictions: u8 {
@@ -3631,13 +3632,9 @@ impl<'a> Parser<'a> {
         let lo = self.span.lo;
         let pat = self.parse_pat();
 
-        let mut ty = P(Ty {
-            id: ast::DUMMY_NODE_ID,
-            node: TyInfer,
-            span: mk_sp(lo, lo),
-        });
+        let mut ty = None;
         if self.eat(&token::Colon) {
-            ty = self.parse_ty_sum();
+            ty = Some(self.parse_ty_sum());
         }
         let init = self.parse_initializer();
         P(ast::Local {
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index f22a4b5c6ed..2745b7e13e9 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -22,8 +22,10 @@ use util::interner::{RcStr, StrInterner};
 use util::interner;
 
 use serialize::{Decodable, Decoder, Encodable, Encoder};
+use std::cmp::Equiv;
 use std::fmt;
 use std::mem;
+use std::ops::Deref;
 use std::path::BytesContainer;
 use std::rc::Rc;
 
@@ -606,7 +608,9 @@ impl InternedString {
     }
 }
 
-impl Deref<str> for InternedString {
+impl Deref for InternedString {
+    type Target = str;
+
     fn deref(&self) -> &str { &*self.string }
 }
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 877b2c7b7d3..64eb4192bf0 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1858,13 +1858,11 @@ impl<'a> State<'a> {
 
     pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> {
         try!(self.print_pat(&*loc.pat));
-        match loc.ty.node {
-            ast::TyInfer => Ok(()),
-            _ => {
-                try!(self.word_space(":"));
-                self.print_type(&*loc.ty)
-            }
+        if let Some(ref ty) = loc.ty {
+            try!(self.word_space(":"));
+            try!(self.print_type(&**ty));
         }
+        Ok(())
     }
 
     pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index 1b3ebde2461..a989b323723 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -10,16 +10,18 @@
 
 //! The AST pointer
 //!
-//! Provides `P<T>`, a frozen owned smart pointer, as a replacement for `@T` in the AST.
+//! Provides `P<T>`, a frozen owned smart pointer, as a replacement for `@T` in
+//! the AST.
 //!
 //! # Motivations and benefits
 //!
-//! * **Identity**: sharing AST nodes is problematic for the various analysis passes
-//!   (e.g. one may be able to bypass the borrow checker with a shared `ExprAddrOf`
-//!   node taking a mutable borrow). The only reason `@T` in the AST hasn't caused
-//!   issues is because of inefficient folding passes which would always deduplicate
-//!   any such shared nodes. Even if the AST were to switch to an arena, this would
-//!   still hold, i.e. it couldn't use `&'a T`, but rather a wrapper like `P<'a, T>`.
+//! * **Identity**: sharing AST nodes is problematic for the various analysis
+//!   passes (e.g. one may be able to bypass the borrow checker with a shared
+//!   `ExprAddrOf` node taking a mutable borrow). The only reason `@T` in the
+//!   AST hasn't caused issues is because of inefficient folding passes which
+//!   would always deduplicate any such shared nodes. Even if the AST were to
+//!   switch to an arena, this would still hold, i.e. it couldn't use `&'a T`,
+//!   but rather a wrapper like `P<'a, T>`.
 //!
 //! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
 //!   (unless it contains an `Unsafe` interior, but that may be denied later).
@@ -34,9 +36,9 @@
 //!   implementation changes (using a special thread-local heap, for example).
 //!   Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated.
 
-use std::fmt;
-use std::fmt::Show;
+use std::fmt::{mod, Show};
 use std::hash::Hash;
+use std::ops::Deref;
 use std::ptr;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
@@ -75,7 +77,9 @@ impl<T: 'static> P<T> {
     }
 }
 
-impl<T> Deref<T> for P<T> {
+impl<T> Deref for P<T> {
+    type Target = T;
+
     fn deref<'a>(&'a self) -> &'a T {
         &*self.ptr
     }
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index c1823231e24..5a4d0cc3bd8 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -152,7 +152,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
         let prelude_path = ast::Path {
             span: DUMMY_SP,
             global: false,
-            segments: vec!(
+            segments: vec![
                 ast::PathSegment {
                     identifier: token::str_to_ident("std"),
                     parameters: ast::PathParameters::none(),
@@ -160,7 +160,12 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
                 ast::PathSegment {
                     identifier: token::str_to_ident("prelude"),
                     parameters: ast::PathParameters::none(),
-                }),
+                },
+                ast::PathSegment {
+                    identifier: token::str_to_ident("v1"),
+                    parameters: ast::PathParameters::none(),
+                },
+            ],
         };
 
         let (crates, uses): (Vec<_>, _) = view_items.iter().cloned().partition(|x| {
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 97eb4316583..6e087778de9 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -15,10 +15,12 @@
 use ast::Name;
 
 use std::borrow::BorrowFrom;
-use std::collections::HashMap;
 use std::cell::RefCell;
+use std::cmp::Ordering;
+use std::collections::HashMap;
 use std::fmt;
 use std::hash::Hash;
+use std::ops::Deref;
 use std::rc::Rc;
 
 pub struct Interner<T> {
@@ -124,7 +126,9 @@ impl BorrowFrom<RcStr> for str {
     }
 }
 
-impl Deref<str> for RcStr {
+impl Deref for RcStr {
+    type Target = str;
+
     fn deref(&self) -> &str { self.string[] }
 }
 
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index 946181770c8..953a7ae960e 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -7,9 +7,11 @@
 // <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::SmallVectorRepr::*;
 use self::IntoIterRepr::*;
 
+use std::iter::FromIterator;
 use std::mem;
 use std::slice;
 use std::vec;
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 40ca6354ca6..a1fe63e3f6f 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -54,8 +54,7 @@ pub enum FnKind<'a> {
 /// explicitly, you need to override each method.  (And you also need
 /// to monitor future changes to `Visitor` in case a new method with a
 /// new default implementation gets introduced.)
-pub trait Visitor<'v> {
-
+pub trait Visitor<'v> : Sized {
     fn visit_name(&mut self, _span: Span, _name: Name) {
         // Nothing to do.
     }
@@ -211,7 +210,7 @@ pub fn walk_view_item<'v, V: Visitor<'v>>(visitor: &mut V, vi: &'v ViewItem) {
 
 pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
     visitor.visit_pat(&*local.pat);
-    visitor.visit_ty(&*local.ty);
+    walk_ty_opt(visitor, &local.ty);
     walk_expr_opt(visitor, &local.init);
 }
 
@@ -381,6 +380,13 @@ pub fn skip_ty<'v, V: Visitor<'v>>(_: &mut V, _: &'v Ty) {
     // Empty!
 }
 
+pub fn walk_ty_opt<'v, V: Visitor<'v>>(visitor: &mut V, optional_type: &'v Option<P<Ty>>) {
+    match *optional_type {
+        Some(ref ty) => visitor.visit_ty(&**ty),
+        None => ()
+    }
+}
+
 pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
     match typ.node {
         TyVec(ref ty) | TyParen(ref ty) => {
@@ -583,10 +589,7 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
 pub fn walk_ty_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v TyParam) {
     visitor.visit_ident(param.span, param.ident);
     walk_ty_param_bounds_helper(visitor, &param.bounds);
-    match param.default {
-        Some(ref ty) => visitor.visit_ty(&**ty),
-        None => {}
-    }
+    walk_ty_opt(visitor, &param.default);
 }
 
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 19821ecb7ca..b2d3611fc64 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -31,8 +31,10 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
+#![allow(unknown_features)]
 #![feature(asm, macro_rules, phase, globs, slicing_syntax)]
 #![feature(unboxed_closures, default_type_params)]
+#![feature(old_orphan_check)]
 
 extern crate getopts;
 extern crate regex;
@@ -49,8 +51,6 @@ use self::TestEvent::*;
 use self::NamePadding::*;
 use self::OutputLocation::*;
 
-use std::any::{Any, AnyRefExt};
-use std::collections::BTreeMap;
 use stats::Stats;
 use getopts::{OptGroup, optflag, optopt};
 use regex::Regex;
@@ -58,7 +58,9 @@ use serialize::{json, Decodable, Encodable};
 use term::Terminal;
 use term::color::{Color, RED, YELLOW, GREEN, CYAN};
 
+use std::any::{Any, AnyRefExt};
 use std::cmp;
+use std::collections::BTreeMap;
 use std::f64;
 use std::fmt::Show;
 use std::fmt;
@@ -69,11 +71,11 @@ use std::io;
 use std::iter::repeat;
 use std::num::{Float, FloatMath, Int};
 use std::os;
-use std::str::FromStr;
-use std::string::String;
+use std::str::{FromStr, from_str};
+use std::sync::mpsc::{channel, Sender};
 use std::thread::{mod, Thread};
-use std::time::Duration;
 use std::thunk::{Thunk, Invoke};
+use std::time::Duration;
 
 // to be used by rustc to compile tests in libtest
 pub mod test {
@@ -171,14 +173,14 @@ impl TestFn {
 
 impl fmt::Show for TestFn {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write(match *self {
+        f.write_str(match *self {
             StaticTestFn(..) => "StaticTestFn(..)",
             StaticBenchFn(..) => "StaticBenchFn(..)",
             StaticMetricFn(..) => "StaticMetricFn(..)",
             DynTestFn(..) => "DynTestFn(..)",
             DynMetricFn(..) => "DynMetricFn(..)",
             DynBenchFn(..) => "DynBenchFn(..)"
-        }.as_bytes())
+        })
     }
 }
 
@@ -1021,7 +1023,7 @@ fn run_tests<F>(opts: &TestOpts,
             pending += 1;
         }
 
-        let (desc, result, stdout) = rx.recv();
+        let (desc, result, stdout) = rx.recv().unwrap();
         if concurrency != 1 {
             try!(callback(TeWait(desc.clone(), PadNone)));
         }
@@ -1034,7 +1036,7 @@ fn run_tests<F>(opts: &TestOpts,
     for b in filtered_benchs_and_metrics.into_iter() {
         try!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
         run_test(opts, !opts.run_benchmarks, b, tx.clone());
-        let (test, result, stdout) = rx.recv();
+        let (test, result, stdout) = rx.recv().unwrap();
         try!(callback(TeResult(test, result, stdout)));
     }
     Ok(())
@@ -1111,7 +1113,7 @@ pub fn run_test(opts: &TestOpts,
     let TestDescAndFn {desc, testfn} = test;
 
     if force_ignore || desc.ignore {
-        monitor_ch.send((desc, TrIgnored, Vec::new()));
+        monitor_ch.send((desc, TrIgnored, Vec::new())).unwrap();
         return;
     }
 
@@ -1138,31 +1140,31 @@ pub fn run_test(opts: &TestOpts,
             let result_guard = cfg.spawn(move || { testfn.invoke(()) });
             let stdout = reader.read_to_end().unwrap().into_iter().collect();
             let test_result = calc_result(&desc, result_guard.join());
-            monitor_ch.send((desc.clone(), test_result, stdout));
+            monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
         }).detach();
     }
 
     match testfn {
         DynBenchFn(bencher) => {
             let bs = ::bench::benchmark(|harness| bencher.run(harness));
-            monitor_ch.send((desc, TrBench(bs), Vec::new()));
+            monitor_ch.send((desc, TrBench(bs), Vec::new())).unwrap();
             return;
         }
         StaticBenchFn(benchfn) => {
             let bs = ::bench::benchmark(|harness| (benchfn.clone())(harness));
-            monitor_ch.send((desc, TrBench(bs), Vec::new()));
+            monitor_ch.send((desc, TrBench(bs), Vec::new())).unwrap();
             return;
         }
         DynMetricFn(f) => {
             let mut mm = MetricMap::new();
             f.invoke(&mut mm);
-            monitor_ch.send((desc, TrMetrics(mm), Vec::new()));
+            monitor_ch.send((desc, TrMetrics(mm), Vec::new())).unwrap();
             return;
         }
         StaticMetricFn(f) => {
             let mut mm = MetricMap::new();
             f(&mut mm);
-            monitor_ch.send((desc, TrMetrics(mm), Vec::new()));
+            monitor_ch.send((desc, TrMetrics(mm), Vec::new())).unwrap();
             return;
         }
         DynTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, f),
@@ -1212,8 +1214,7 @@ impl MetricMap {
     pub fn save(&self, p: &Path) -> io::IoResult<()> {
         let mut file = try!(File::create(p));
         let MetricMap(ref map) = *self;
-        let mut enc = json::PrettyEncoder::new(&mut file);
-        map.encode(&mut enc)
+        write!(&mut file, "{}", json::as_json(map))
     }
 
     /// Compare against another MetricMap. Optionally compare all
@@ -1466,6 +1467,7 @@ mod tests {
                StaticTestName, DynTestName, DynTestFn, ShouldFail};
     use std::io::TempDir;
     use std::thunk::Thunk;
+    use std::sync::mpsc::channel;
 
     #[test]
     pub fn do_not_run_ignored_tests() {
@@ -1480,7 +1482,7 @@ mod tests {
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
-        let (_, res, _) = rx.recv();
+        let (_, res, _) = rx.recv().unwrap();
         assert!(res != TrOk);
     }
 
@@ -1497,7 +1499,7 @@ mod tests {
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
-        let (_, res, _) = rx.recv();
+        let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrIgnored);
     }
 
@@ -1514,7 +1516,7 @@ mod tests {
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
-        let (_, res, _) = rx.recv();
+        let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrOk);
     }
 
@@ -1531,7 +1533,7 @@ mod tests {
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
-        let (_, res, _) = rx.recv();
+        let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrOk);
     }
 
@@ -1548,7 +1550,7 @@ mod tests {
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
-        let (_, res, _) = rx.recv();
+        let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrFailed);
     }
 
@@ -1565,7 +1567,7 @@ mod tests {
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
-        let (_, res, _) = rx.recv();
+        let (_, res, _) = rx.recv().unwrap();
         assert!(res == TrFailed);
     }
 
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index 41146cded70..ed6a00a8e91 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -10,13 +10,14 @@
 
 #![allow(missing_docs)]
 
-use std::collections::hash_map;
+use std::cmp::Ordering::{mod, Less, Greater, Equal};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::collections::hash_map;
 use std::fmt::Show;
 use std::hash::Hash;
 use std::io;
 use std::mem;
-use std::num::{Float, FloatMath};
+use std::num::{Float, FloatMath, FromPrimitive};
 
 fn local_cmp<T:Float>(x: T, y: T) -> Ordering {
     // arbitrarily decide that NaNs are larger than everything.
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index 87a00334c47..bc5d0c21aae 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -20,7 +20,10 @@
        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(phase, globs)]
+#![feature(old_orphan_check)]
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 
@@ -30,10 +33,9 @@ extern crate libc;
 pub use self::ParseError::*;
 use self::Fmt::*;
 
-use std::fmt::Show;
-use std::fmt;
+use std::fmt::{mod, Show};
 use std::num::SignedInt;
-use std::string::String;
+use std::ops::{Add, Sub};
 use std::time::Duration;
 
 static NSEC_PER_SEC: i32 = 1_000_000_000_i32;
@@ -198,7 +200,7 @@ pub fn precise_time_ns() -> u64 {
                                                                                    denom: 0 };
         static ONCE: std::sync::Once = std::sync::ONCE_INIT;
         unsafe {
-            ONCE.doit(|| {
+            ONCE.call_once(|| {
                 imp::mach_timebase_info(&mut TIMEBASE);
             });
             let time = imp::mach_absolute_time();
@@ -1274,6 +1276,7 @@ mod tests {
     #[cfg(windows)]
     fn set_time_zone() {
         use libc;
+        use std::c_str::ToCStr;
         // Windows crt doesn't see any environment variable set by
         // `SetEnvironmentVariable`, which `os::setenv` internally uses.
         // It is why we use `putenv` here.
diff --git a/src/snapshots.txt b/src/snapshots.txt
index 6a9bfa07cf7..34beb53bd07 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,3 +1,12 @@
+S 2015-01-01 7d4f487
+  freebsd-x86_64 5dc87adb17bc33abc08f1bf4c092e0b5b92a6ca4
+  linux-i386 63bf82a5b540d8acbbf1e445ce48be0fa0f003fc
+  linux-x86_64 b1a414355ef5d2feff18ab9d008a2e9afc7b4625
+  macos-i386 26042e3e648eb40848bf02f3e05ba31fd686179c
+  macos-x86_64 f01d7c6faf5db480a18a521c6971364f4ce8ddca
+  winnt-i386 6f04af045d26a0c87d487ba7254d4ad0c166ecaf
+  winnt-x86_64 392ab49482ec926de6a167afe920518b9a502a3f
+
 S 2014-12-30 023dfb0
   freebsd-x86_64 41ecd0ac557c823831c46696c7d78dc250398f25
   linux-i386 fe6b59bf70a397e18629cb82264f7c6a70df34d4
diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs
index 1cccb0f7ccb..ec470ddc213 100644
--- a/src/test/auxiliary/cci_capture_clause.rs
+++ b/src/test/auxiliary/cci_capture_clause.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::task;
+use std::sync::mpsc::{Receiver, channel};
 
 pub fn foo<T:Send + Clone>(x: T) -> Receiver<T> {
     let (tx, rx) = channel();
diff --git a/src/test/auxiliary/coherence-lib.rs b/src/test/auxiliary/coherence-lib.rs
new file mode 100644
index 00000000000..daa123849e4
--- /dev/null
+++ b/src/test/auxiliary/coherence-lib.rs
@@ -0,0 +1,25 @@
+// 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.
+
+#![crate_type="lib"]
+
+pub trait Remote {
+    fn foo(&self) { }
+}
+
+pub trait Remote1<T> {
+    fn foo(&self, t: T) { }
+}
+
+pub trait Remote2<T, U> {
+    fn foo(&self, t: T, u: U) { }
+}
+
+pub struct Pair<T,U>(T,U);
diff --git a/src/test/auxiliary/issue-17718.rs b/src/test/auxiliary/issue-17718.rs
index f0b431b1db9..689610d799e 100644
--- a/src/test/auxiliary/issue-17718.rs
+++ b/src/test/auxiliary/issue-17718.rs
@@ -11,12 +11,12 @@
 use std::sync::atomic;
 
 pub const C1: uint = 1;
-pub const C2: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+pub const C2: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
 pub const C3: fn() = foo;
 pub const C4: uint = C1 * C1 + C1 / C1;
 pub const C5: &'static uint = &C4;
 
 pub static S1: uint = 3;
-pub static S2: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+pub static S2: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
 
 fn foo() {}
diff --git a/src/test/bench/spawnone.rs b/src/test/auxiliary/issue_20389.rs
index ca36d99014c..60e3cb13e2e 100644
--- a/src/test/bench/spawnone.rs
+++ b/src/test/auxiliary/issue_20389.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 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,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Useful for checking syscall usage of baseline scheduler usage
-fn main() {
-    spawn(move|| {});
+#![feature(associated_types)]
+
+pub trait T {
+    type C;
 }
diff --git a/src/test/auxiliary/method_self_arg2.rs b/src/test/auxiliary/method_self_arg2.rs
index e1e79b59e3e..eb4d62b01ad 100644
--- a/src/test/auxiliary/method_self_arg2.rs
+++ b/src/test/auxiliary/method_self_arg2.rs
@@ -32,7 +32,7 @@ impl Foo {
     }
 }
 
-pub trait Bar {
+pub trait Bar : Sized {
     fn foo1(&self);
     fn foo2(self);
     fn foo3(self: Box<Self>);
diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs
index 26d61e166f2..05960a5b8e1 100644
--- a/src/test/auxiliary/overloaded_autoderef_xc.rs
+++ b/src/test/auxiliary/overloaded_autoderef_xc.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
@@ -24,7 +26,9 @@ impl<T> Helper<T> for Option<T> {
     }
 }
 
-impl<T, H: Helper<T>> Deref<T> for DerefWithHelper<H, T> {
+impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
+    type Target = T;
+
     fn deref(&self) -> &T {
         self.helper.helper_borrow()
     }
diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/auxiliary/static-methods-crate.rs
index 811d8f11692..ea4751bf4ed 100644
--- a/src/test/auxiliary/static-methods-crate.rs
+++ b/src/test/auxiliary/static-methods-crate.rs
@@ -12,6 +12,7 @@
 #![crate_type = "lib"]
 
 use std::int;
+use std::str::from_str;
 
 pub trait read {
     fn readMaybe(s: String) -> Option<Self>;
diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
index 0e90db2835f..7ddf2c43489 100644
--- a/src/test/auxiliary/trait_inheritance_overloading_xc.rs
+++ b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::cmp::PartialEq;
+use std::ops::{Add, Sub, Mul};
 
 pub trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq + Clone {
 }
diff --git a/src/test/auxiliary/traitimpl.rs b/src/test/auxiliary/traitimpl.rs
new file mode 100644
index 00000000000..fd454509b39
--- /dev/null
+++ b/src/test/auxiliary/traitimpl.rs
@@ -0,0 +1,17 @@
+// 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.
+
+// Test inherant trait impls work cross-crait.
+
+pub trait Bar<'a> for ?Sized : 'a {}
+
+impl<'a> Bar<'a> {
+    pub fn bar(&self) {}
+}
diff --git a/src/test/auxiliary/unboxed-closures-cross-crate.rs b/src/test/auxiliary/unboxed-closures-cross-crate.rs
index 9a6a2c7495b..0b65fa913cb 100644
--- a/src/test/auxiliary/unboxed-closures-cross-crate.rs
+++ b/src/test/auxiliary/unboxed-closures-cross-crate.rs
@@ -10,6 +10,8 @@
 
 #![feature(unboxed_closures)]
 
+use std::ops::Add;
+
 #[inline]
 pub fn has_closures() -> uint {
     let x = 1u;
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index 60331dfb550..0ada1cb991c 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -13,6 +13,7 @@
 use std::collections::{BTreeMap, HashMap, HashSet};
 use std::os;
 use std::rand::{Rng, IsaacRng, SeedableRng};
+use std::str::from_str;
 use std::time::Duration;
 use std::uint;
 
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 49f5c7751d9..52380001c6c 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -15,11 +15,12 @@
 extern crate collections;
 extern crate rand;
 
+use std::collections::BTreeSet;
 use std::collections::BitvSet;
 use std::collections::HashSet;
-use std::collections::BTreeSet;
 use std::hash::Hash;
 use std::os;
+use std::str::from_str;
 use std::time::Duration;
 use std::uint;
 
diff --git a/src/test/bench/core-uint-to-str.rs b/src/test/bench/core-uint-to-str.rs
index 98113cb8347..08637b4bf1c 100644
--- a/src/test/bench/core-uint-to-str.rs
+++ b/src/test/bench/core-uint-to-str.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::os;
+use std::str::from_str;
 use std::uint;
 
 fn main() {
diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs
index 645c029f935..285d193e7da 100644
--- a/src/test/bench/msgsend-pipes-shared.rs
+++ b/src/test/bench/msgsend-pipes-shared.rs
@@ -18,8 +18,9 @@
 // different scalability characteristics compared to the select
 // version.
 
-use std::comm;
+use std::sync::mpsc::{channel, Sender, Receiver};
 use std::os;
+use std::str::from_str;
 use std::thread::Thread;
 use std::time::Duration;
 use std::uint;
@@ -36,8 +37,8 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
     let mut count = 0u;
     let mut done = false;
     while !done {
-        match requests.recv_opt() {
-          Ok(request::get_count) => { responses.send(count.clone()); }
+        match requests.recv() {
+          Ok(request::get_count) => { responses.send(count.clone()).unwrap(); }
           Ok(request::bytes(b)) => {
             //println!("server: received {} bytes", b);
             count += b;
@@ -46,7 +47,7 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
           _ => { }
         }
     }
-    responses.send(count);
+    responses.send(count).unwrap();
     //println!("server exiting");
 }
 
@@ -67,7 +68,7 @@ fn run(args: &[String]) {
             worker_results.push(Thread::spawn(move|| {
                 for _ in range(0u, size / workers) {
                     //println!("worker {}: sending {} bytes", i, num_bytes);
-                    to_child.send(request::bytes(num_bytes));
+                    to_child.send(request::bytes(num_bytes)).unwrap();
                 }
                 //println!("worker {} exiting", i);
             }));
@@ -81,9 +82,9 @@ fn run(args: &[String]) {
         }
 
         //println!("sending stop message");
-        to_child.send(request::stop);
+        to_child.send(request::stop).unwrap();
         move_out(to_child);
-        result = Some(from_child.recv());
+        result = Some(from_child.recv().unwrap());
     });
     let result = result.unwrap();
     print!("Count is {}\n", result);
diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs
index ed96c6406d8..ef22aac776e 100644
--- a/src/test/bench/msgsend-pipes.rs
+++ b/src/test/bench/msgsend-pipes.rs
@@ -14,6 +14,7 @@
 //
 // I *think* it's the same, more or less.
 
+use std::sync::mpsc::{channel, Sender, Receiver};
 use std::os;
 use std::thread::Thread;
 use std::time::Duration;
@@ -31,7 +32,7 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
     let mut count: uint = 0;
     let mut done = false;
     while !done {
-        match requests.recv_opt() {
+        match requests.recv() {
           Ok(request::get_count) => { responses.send(count.clone()); }
           Ok(request::bytes(b)) => {
             //println!("server: received {} bytes", b);
@@ -48,8 +49,8 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
 fn run(args: &[String]) {
     let (to_parent, from_child) = channel();
 
-    let size = from_str::<uint>(args[1].as_slice()).unwrap();
-    let workers = from_str::<uint>(args[2].as_slice()).unwrap();
+    let size = args[1].parse::<uint>().unwrap();
+    let workers = args[2].parse::<uint>().unwrap();
     let num_bytes = 100;
     let mut result = None;
     let mut to_parent = Some(to_parent);
@@ -91,7 +92,7 @@ fn run(args: &[String]) {
         //println!("sending stop message");
         //to_child.send(stop);
         //move_out(to_child);
-        result = Some(from_child.recv());
+        result = Some(from_child.recv().unwrap());
     });
     let result = result.unwrap();
     print!("Count is {}\n", result);
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs
index 8ec44b2dd3c..3ead5ef64fd 100644
--- a/src/test/bench/msgsend-ring-mutex-arcs.rs
+++ b/src/test/bench/msgsend-ring-mutex-arcs.rs
@@ -19,6 +19,7 @@
 // ignore-lexer-test FIXME #15679
 
 use std::os;
+use std::str::from_str;
 use std::sync::{Arc, Future, Mutex, Condvar};
 use std::time::Duration;
 use std::uint;
diff --git a/src/test/bench/rt-messaging-ping-pong.rs b/src/test/bench/rt-messaging-ping-pong.rs
index 73d54372b27..de9e6629fbf 100644
--- a/src/test/bench/rt-messaging-ping-pong.rs
+++ b/src/test/bench/rt-messaging-ping-pong.rs
@@ -17,7 +17,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
 use std::os;
+use std::str::from_str;
+use std::thread::Thread;
 use std::uint;
 
 // This is a simple bench that creates M pairs of tasks. These
@@ -34,21 +37,21 @@ fn ping_pong_bench(n: uint, m: uint) {
         // Create a stream B->A
         let (btx, brx) = channel::<()>();
 
-        spawn(move|| {
+        Thread::spawn(move|| {
             let (tx, rx) = (atx, brx);
             for _ in range(0, n) {
                 tx.send(());
                 rx.recv();
             }
-        });
+        }).detach();
 
-        spawn(move|| {
+        Thread::spawn(move|| {
             let (tx, rx) = (btx, arx);
             for _ in range(0, n) {
                 rx.recv();
                 tx.send(());
             }
-        });
+        }).detach();
     }
 
     for _ in range(0, m) {
diff --git a/src/test/bench/rt-parfib.rs b/src/test/bench/rt-parfib.rs
index bdf22cd7395..8b212555d40 100644
--- a/src/test/bench/rt-parfib.rs
+++ b/src/test/bench/rt-parfib.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
 use std::os;
+use std::thread::Thread;
 use std::uint;
 
 // A simple implementation of parfib. One subtree is found in a new
@@ -21,11 +23,11 @@ fn parfib(n: uint) -> uint {
     }
 
     let (tx, rx) = channel();
-    spawn(move|| {
+    Thread::spawn(move|| {
         tx.send(parfib(n-1));
-    });
+    }).detach();
     let m2 = parfib(n-2);
-    return (rx.recv() + m2);
+    return (rx.recv().unwrap() + m2);
 }
 
 fn main() {
@@ -33,7 +35,7 @@ fn main() {
     let args = os::args();
     let args = args.as_slice();
     let n = if args.len() == 2 {
-        from_str::<uint>(args[1].as_slice()).unwrap()
+        args[1].parse::<uint>().unwrap()
     } else {
         10
     };
diff --git a/src/test/bench/shootout-ackermann.rs b/src/test/bench/shootout-ackermann.rs
index e7a50382c94..f7810d5d740 100644
--- a/src/test/bench/shootout-ackermann.rs
+++ b/src/test/bench/shootout-ackermann.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::os;
+use std::str::from_str;
 
 fn ack(m: int, n: int) -> int {
     if m == 0 {
diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs
index 0b16e8011e8..c7a43d61a9a 100644
--- a/src/test/bench/shootout-binarytrees.rs
+++ b/src/test/bench/shootout-binarytrees.rs
@@ -41,7 +41,7 @@
 extern crate arena;
 
 use std::iter::range_step;
-use std::sync::Future;
+use std::thread::Thread;
 use arena::TypedArena;
 
 enum Tree<'a> {
@@ -75,7 +75,7 @@ fn main() {
     } else if args.len() <= 1u {
         8
     } else {
-        from_str(args[1].as_slice()).unwrap()
+        args[1].parse().unwrap()
     };
     let min_depth = 4;
     let max_depth = if min_depth + 2 > n {min_depth + 2} else {n};
@@ -95,7 +95,7 @@ fn main() {
     let mut messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
             use std::num::Int;
             let iterations = 2i.pow((max_depth - depth + min_depth) as uint);
-            Future::spawn(move|| {
+            Thread::spawn(move|| {
                 let mut chk = 0;
                 for i in range(1, iterations + 1) {
                     let arena = TypedArena::new();
@@ -106,10 +106,10 @@ fn main() {
                 format!("{}\t trees of depth {}\t check: {}",
                         iterations * 2, depth, chk)
             })
-        }).collect::<Vec<Future<String>>>();
+        }).collect::<Vec<_>>();
 
-    for message in messages.iter_mut() {
-        println!("{}", *message.get_ref());
+    for message in messages.into_iter() {
+        println!("{}", message.join().ok().unwrap());
     }
 
     println!("long lived tree of depth {}\t check: {}",
diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs
index dcdb90a11c8..030c627b6f7 100644
--- a/src/test/bench/shootout-chameneos-redux.rs
+++ b/src/test/bench/shootout-chameneos-redux.rs
@@ -41,8 +41,10 @@
 // no-pretty-expanded
 
 use self::Color::{Red, Yellow, Blue};
-use std::string::String;
+use std::sync::mpsc::{channel, Sender, Receiver};
 use std::fmt;
+use std::str::from_str;
+use std::thread::Thread;
 
 fn print_complements() {
     let all = [Blue, Red, Yellow];
@@ -152,7 +154,7 @@ fn creature(
 
     loop {
         // ask for a pairing
-        to_rendezvous.send(CreatureInfo {name: name, color: color});
+        to_rendezvous.send(CreatureInfo {name: name, color: color}).unwrap();
 
         // log and change, or quit
         match rendezvous.next() {
@@ -170,7 +172,7 @@ fn creature(
     }
     // log creatures met and evil clones of self
     let report = format!("{}{}", creatures_met, Number(evil_clones_met));
-    to_rendezvous_log.send(report);
+    to_rendezvous_log.send(report).unwrap();
 }
 
 fn rendezvous(nn: uint, set: Vec<Color>) {
@@ -188,13 +190,13 @@ fn rendezvous(nn: uint, set: Vec<Color>) {
             let to_rendezvous = to_rendezvous.clone();
             let to_rendezvous_log = to_rendezvous_log.clone();
             let (to_creature, from_rendezvous) = channel();
-            spawn(move|| {
+            Thread::spawn(move|| {
                 creature(ii,
                          col,
                          from_rendezvous,
                          to_rendezvous,
                          to_rendezvous_log);
-            });
+            }).detach();
             to_creature
         }).collect();
 
@@ -202,13 +204,13 @@ fn rendezvous(nn: uint, set: Vec<Color>) {
 
     // set up meetings...
     for _ in range(0, nn) {
-        let fst_creature = from_creatures.recv();
-        let snd_creature = from_creatures.recv();
+        let fst_creature = from_creatures.recv().unwrap();
+        let snd_creature = from_creatures.recv().unwrap();
 
         creatures_met += 2;
 
-        to_creature[fst_creature.name].send(snd_creature);
-        to_creature[snd_creature.name].send(fst_creature);
+        to_creature[fst_creature.name].send(snd_creature).unwrap();
+        to_creature[snd_creature.name].send(fst_creature).unwrap();
     }
 
     // tell each creature to stop
diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs
index ef38f5ef743..7dca2b24fc1 100644
--- a/src/test/bench/shootout-fannkuch-redux.rs
+++ b/src/test/bench/shootout-fannkuch-redux.rs
@@ -41,7 +41,7 @@
 #![feature(slicing_syntax)]
 
 use std::{cmp, iter, mem};
-use std::sync::Future;
+use std::thread::Thread;
 
 fn rotate(x: &mut [i32]) {
     let mut prev = x[0];
@@ -168,15 +168,15 @@ fn fannkuch(n: i32) -> (i32, i32) {
     for (i, j) in range(0, N).zip(iter::count(0, k)) {
         let max = cmp::min(j+k, perm.max());
 
-        futures.push(Future::spawn(move|| {
+        futures.push(Thread::spawn(move|| {
             work(perm, j as uint, max as uint)
         }))
     }
 
     let mut checksum = 0;
     let mut maxflips = 0;
-    for fut in futures.iter_mut() {
-        let (cs, mf) = fut.get();
+    for fut in futures.into_iter() {
+        let (cs, mf) = fut.join().ok().unwrap();
         checksum += cs;
         maxflips = cmp::max(maxflips, mf);
     }
@@ -186,7 +186,7 @@ fn fannkuch(n: i32) -> (i32, i32) {
 fn main() {
     let n = std::os::args().as_slice()
         .get(1)
-        .and_then(|arg| from_str(arg.as_slice()))
+        .and_then(|arg| arg.parse())
         .unwrap_or(2i32);
 
     let (checksum, maxflips) = fannkuch(n);
diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs
index 178d6777939..09f7f236f19 100644
--- a/src/test/bench/shootout-fasta-redux.rs
+++ b/src/test/bench/shootout-fasta-redux.rs
@@ -44,6 +44,7 @@ use std::cmp::min;
 use std::io::{stdout, IoResult};
 use std::os;
 use std::slice::bytes::copy_memory;
+use std::str::from_str;
 
 const LINE_LEN: uint = 60;
 const LOOKUP_SIZE: uint = 4 * 1024;
diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs
index 2de61cf3572..7009dd4c1a7 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -40,11 +40,12 @@
 
 #![feature(slicing_syntax)]
 
-use std::io;
-use std::io::{BufferedWriter, File};
 use std::cmp::min;
+use std::io::{BufferedWriter, File};
+use std::io;
 use std::num::Float;
 use std::os;
+use std::str::from_str;
 
 const LINE_LENGTH: uint = 60;
 const IM: u32 = 139968;
diff --git a/src/test/bench/shootout-fibo.rs b/src/test/bench/shootout-fibo.rs
index 10c0d0a8044..cbacf415f6f 100644
--- a/src/test/bench/shootout-fibo.rs
+++ b/src/test/bench/shootout-fibo.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::os;
+use std::str::from_str;
 
 fn fib(n: int) -> int {
     if n < 2 {
diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs
index f49b648e215..d92d30ca844 100644
--- a/src/test/bench/shootout-k-nucleotide-pipes.rs
+++ b/src/test/bench/shootout-k-nucleotide-pipes.rs
@@ -18,12 +18,15 @@
 extern crate collections;
 
 use std::ascii::{AsciiExt, OwnedAsciiExt};
+use std::cmp::Ordering::{mod, Less, Greater, Equal};
 use std::collections::HashMap;
+use std::sync::mpsc::{channel, Sender, Receiver};
 use std::mem::replace;
 use std::num::Float;
 use std::option;
 use std::os;
-use std::string::String;
+use std::string::IntoString;
+use std::thread::Thread;
 
 fn f64_cmp(x: f64, y: f64) -> Ordering {
     // arbitrarily decide that NaNs are larger than everything.
@@ -117,7 +120,7 @@ fn make_sequence_processor(sz: uint,
 
    loop {
 
-       line = from_parent.recv();
+       line = from_parent.recv().unwrap();
        if line == Vec::new() { break; }
 
        carry.push_all(line.as_slice());
@@ -167,9 +170,9 @@ fn main() {
 
         let (to_child, from_parent) = channel();
 
-        spawn(move|| {
+        Thread::spawn(move|| {
             make_sequence_processor(sz, &from_parent, &to_parent_);
-        });
+        }).detach();
 
         to_child
     }).collect::<Vec<Sender<Vec<u8> >> >();
@@ -219,6 +222,6 @@ fn main() {
 
    // now fetch and print result messages
    for (ii, _sz) in sizes.iter().enumerate() {
-       println!("{}", from_child[ii].recv());
+       println!("{}", from_child[ii].recv().unwrap());
    }
 }
diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs
index 1408cfe6eee..26ef696b616 100644
--- a/src/test/bench/shootout-k-nucleotide.rs
+++ b/src/test/bench/shootout-k-nucleotide.rs
@@ -43,7 +43,6 @@
 #![feature(slicing_syntax)]
 
 use std::ascii::OwnedAsciiExt;
-use std::string::String;
 use std::slice;
 use std::sync::{Arc, Future};
 
diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs
index bb0e09370d8..51ce4cbaa84 100644
--- a/src/test/bench/shootout-mandelbrot.rs
+++ b/src/test/bench/shootout-mandelbrot.rs
@@ -47,6 +47,7 @@
 use std::io;
 use std::os;
 use std::simd::f64x2;
+use std::str::from_str;
 use std::sync::{Arc, Future};
 
 const ITER: int = 50;
diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs
index 9a3b6953062..0c3152d4780 100644
--- a/src/test/bench/shootout-meteor.rs
+++ b/src/test/bench/shootout-meteor.rs
@@ -40,7 +40,9 @@
 
 // no-pretty-expanded FIXME #15189
 
+use std::sync::mpsc::channel;
 use std::sync::Arc;
+use std::thread::Thread;
 
 //
 // Utilities.
@@ -310,16 +312,16 @@ fn par_search(masks: Vec<Vec<Vec<u64>>>) -> Data {
         let masks = masks.clone();
         let tx = tx.clone();
         let m = *m;
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut data = Data::new();
             search(&*masks, m, 1, List::Cons(m, &List::Nil), &mut data);
-            tx.send(data);
-        });
+            tx.send(data).unwrap();
+        }).detach();
     }
 
     // collecting the results
     drop(tx);
-    let mut data = rx.recv();
+    let mut data = rx.recv().unwrap();
     for d in rx.iter() { data.reduce_from(d); }
     data
 }
diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs
index dab67331120..6a325798f58 100644
--- a/src/test/bench/shootout-nbody.rs
+++ b/src/test/bench/shootout-nbody.rs
@@ -39,6 +39,7 @@
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
 use std::num::Float;
+use std::str::from_str;
 
 const PI: f64 = 3.141592653589793;
 const SOLAR_MASS: f64 = 4.0 * PI * PI;
diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs
index f7e8fc8fe1b..78b5ac00b45 100644
--- a/src/test/bench/shootout-pfib.rs
+++ b/src/test/bench/shootout-pfib.rs
@@ -20,30 +20,32 @@
 
 extern crate getopts;
 
+use std::sync::mpsc::{channel, Sender};
 use std::os;
 use std::result::Result::{Ok, Err};
+use std::str::from_str;
 use std::thread::Thread;
 use std::time::Duration;
 
 fn fib(n: int) -> int {
     fn pfib(tx: &Sender<int>, n: int) {
         if n == 0 {
-            tx.send(0);
+            tx.send(0).unwrap();
         } else if n <= 2 {
-            tx.send(1);
+            tx.send(1).unwrap();
         } else {
             let (tx1, rx) = channel();
             let tx2 = tx1.clone();
             Thread::spawn(move|| pfib(&tx2, n - 1)).detach();
             let tx2 = tx1.clone();
             Thread::spawn(move|| pfib(&tx2, n - 2)).detach();
-            tx.send(rx.recv() + rx.recv());
+            tx.send(rx.recv().unwrap() + rx.recv().unwrap());
         }
     }
 
     let (tx, rx) = channel();
     Thread::spawn(move|| pfib(&tx, n) ).detach();
-    rx.recv()
+    rx.recv().unwrap()
 }
 
 struct Config {
diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs
index 909f8afc34a..d9dfd65d5b3 100644
--- a/src/test/bench/shootout-reverse-complement.rs
+++ b/src/test/bench/shootout-reverse-complement.rs
@@ -45,9 +45,10 @@
 extern crate libc;
 
 use std::io::stdio::{stdin_raw, stdout_raw};
+use std::io::{IoResult, EndOfFile};
 use std::num::{div_rem};
 use std::ptr::{copy_memory, Unique};
-use std::io::{IoResult, EndOfFile};
+use std::thread::Thread;
 
 struct Tables {
     table8: [u8;1 << 8],
@@ -229,26 +230,20 @@ unsafe impl<T: 'static> Send for Racy<T> {}
 fn parallel<'a, I, T, F>(mut iter: I, f: F)
         where T: 'a+Send + Sync,
               I: Iterator<&'a mut [T]>,
-              F: Fn(&'a mut [T]) + Sync {
+              F: Fn(&mut [T]) + Sync {
     use std::mem;
     use std::raw::Repr;
 
-    let (tx, rx) = channel();
-    for chunk in iter {
-        let tx = tx.clone();
-
+    iter.map(|chunk| {
         // Need to convert `f` and `chunk` to something that can cross the task
         // boundary.
         let f = Racy(&f as *const F as *const uint);
         let raw = Racy(chunk.repr());
-        spawn(move|| {
+        Thread::spawn(move|| {
             let f = f.0 as *const F;
             unsafe { (*f)(mem::transmute(raw.0)) }
-            drop(tx)
-        });
-    }
-    drop(tx);
-    for () in rx.iter() {}
+        })
+    }).collect::<Vec<_>>();
 }
 
 fn main() {
diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs
index df388fbdde5..a5af1227a16 100644
--- a/src/test/bench/shootout-spectralnorm.rs
+++ b/src/test/bench/shootout-spectralnorm.rs
@@ -44,11 +44,13 @@
 #![feature(unboxed_closures)]
 
 use std::iter::AdditiveIterator;
+use std::thread::Thread;
 use std::mem;
 use std::num::Float;
 use std::os;
 use std::raw::Repr;
 use std::simd::f64x2;
+use std::str::from_str;
 
 fn main() {
     let args = os::args();
@@ -80,14 +82,15 @@ fn mult_AtAv(v: &[f64], out: &mut [f64], tmp: &mut [f64]) {
 }
 
 fn mult_Av(v: &[f64], out: &mut [f64]) {
-    parallel(out, |&: start, out| mult(v, out, start, |i, j| A(i, j)));
+    parallel(out, |start, out| mult(v, out, start, |i, j| A(i, j)));
 }
 
 fn mult_Atv(v: &[f64], out: &mut [f64]) {
-    parallel(out, |&: start, out| mult(v, out, start, |i, j| A(j, i)));
+    parallel(out, |start, out| mult(v, out, start, |i, j| A(j, i)));
 }
 
-fn mult(v: &[f64], out: &mut [f64], start: uint, a: |uint, uint| -> f64) {
+fn mult<F>(v: &[f64], out: &mut [f64], start: uint, a: F)
+           where F: Fn(uint, uint) -> f64 {
     for (i, slot) in out.iter_mut().enumerate().map(|(i, s)| (i + start, s)) {
         let mut sum = f64x2(0.0, 0.0);
         for (j, chunk) in v.chunks(2).enumerate().map(|(j, s)| (2 * j, s)) {
@@ -116,25 +119,19 @@ unsafe impl<T: 'static> Send for Racy<T> {}
 // Executes a closure in parallel over the given mutable slice. The closure `f`
 // is run in parallel and yielded the starting index within `v` as well as a
 // sub-slice of `v`.
-fn parallel<'a, T, F>(v: &'a mut [T], f: F)
-                      where T: Send + Sync,
-                            F: Fn(uint, &'a mut [T]) + Sync {
-    let (tx, rx) = channel();
+fn parallel<T, F>(v: &mut [T], f: F)
+                  where T: Send + Sync,
+                        F: Fn(uint, &mut [T]) + Sync {
     let size = v.len() / os::num_cpus() + 1;
 
-    for (i, chunk) in v.chunks_mut(size).enumerate() {
-        let tx = tx.clone();
-
+    v.chunks_mut(size).enumerate().map(|(i, chunk)| {
         // Need to convert `f` and `chunk` to something that can cross the task
         // boundary.
         let f = Racy(&f as *const _ as *const uint);
         let raw = Racy(chunk.repr());
-        spawn(move|| {
+        Thread::spawn(move|| {
             let f = f.0 as *const F;
             unsafe { (*f)(i * size, mem::transmute(raw.0)) }
-            drop(tx)
-        });
-    }
-    drop(tx);
-    for () in rx.iter() {}
+        })
+    }).collect::<Vec<_>>();
 }
diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs
index 111a92b083a..543597d8c81 100644
--- a/src/test/bench/shootout-threadring.rs
+++ b/src/test/bench/shootout-threadring.rs
@@ -38,15 +38,19 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
+use std::sync::mpsc::{channel, Sender, Receiver};
+use std::str::from_str;
+use std::thread::Thread;
+
 fn start(n_tasks: int, token: int) {
     let (tx, mut rx) = channel();
     tx.send(token);
     for i in range(2, n_tasks + 1) {
         let (tx, next_rx) = channel();
-        spawn(move|| roundtrip(i, tx, rx));
+        Thread::spawn(move|| roundtrip(i, tx, rx)).detach();
         rx = next_rx;
     }
-    spawn(move|| roundtrip(1, tx, rx));
+    Thread::spawn(move|| roundtrip(1, tx, rx)).detach();
 }
 
 fn roundtrip(id: int, tx: Sender<int>, rx: Receiver<int>) {
diff --git a/src/test/bench/std-smallintmap.rs b/src/test/bench/std-smallintmap.rs
index 576d96ba2a3..035b222e6ce 100644
--- a/src/test/bench/std-smallintmap.rs
+++ b/src/test/bench/std-smallintmap.rs
@@ -12,6 +12,7 @@
 
 use std::collections::VecMap;
 use std::os;
+use std::str::from_str;
 use std::time::Duration;
 use std::uint;
 
diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs
index 5fb7e2c3a84..cccc9362a72 100644
--- a/src/test/bench/sudoku.rs
+++ b/src/test/bench/sudoku.rs
@@ -12,11 +12,12 @@
 
 #![allow(non_snake_case)]
 
-use std::io;
-use std::io::stdio::StdReader;
 use std::io::BufferedReader;
+use std::io::stdio::StdReader;
+use std::io;
 use std::num::Int;
 use std::os;
+use std::str::from_str;
 
 // Computes a single solution to a given 9x9 sudoku
 //
diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs
index 789ccb6142a..a0278a63a51 100644
--- a/src/test/bench/task-perf-jargon-metal-smoke.rs
+++ b/src/test/bench/task-perf-jargon-metal-smoke.rs
@@ -17,25 +17,27 @@
 
 // ignore-pretty very bad with line comments
 
-use std::comm;
+use std::sync::mpsc::{channel, Sender};
 use std::os;
+use std::str::from_str;
 use std::task;
+use std::thread::Thread;
 use std::uint;
 
-fn child_generation(gens_left: uint, tx: comm::Sender<()>) {
+fn child_generation(gens_left: uint, tx: Sender<()>) {
     // This used to be O(n^2) in the number of generations that ever existed.
     // With this code, only as many generations are alive at a time as tasks
     // alive at a time,
-    spawn(move|| {
+    Thread::spawn(move|| {
         if gens_left & 1 == 1 {
             task::deschedule(); // shake things up a bit
         }
         if gens_left > 0 {
             child_generation(gens_left - 1, tx); // recurse
         } else {
-            tx.send(())
+            tx.send(()).unwrap()
         }
-    });
+    }).detach();
 }
 
 fn main() {
@@ -50,7 +52,7 @@ fn main() {
 
     let (tx, rx) = channel();
     child_generation(from_str::<uint>(args[1].as_slice()).unwrap(), tx);
-    if rx.recv_opt().is_err() {
+    if rx.recv().is_err() {
         panic!("it happened when we slumbered");
     }
 }
diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs
index a6852d396d9..7e2c6fcf0ec 100644
--- a/src/test/bench/task-perf-spawnalot.rs
+++ b/src/test/bench/task-perf-spawnalot.rs
@@ -11,6 +11,7 @@
 use std::os;
 use std::task;
 use std::uint;
+use std::str::from_str;
 
 fn f(n: uint) {
     let mut i = 0u;
diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
new file mode 100644
index 00000000000..5743216b6ca
--- /dev/null
+++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
@@ -0,0 +1,34 @@
+// 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.
+
+// Test that we do not ICE when the self type is `ty::err`, but rather
+// just propagate the error.
+
+#![crate_type = "lib"]
+#![feature(associated_types, default_type_params, lang_items)]
+#![no_std]
+
+#[lang="sized"]
+pub trait Sized for Sized? {
+    // Empty.
+}
+
+#[lang = "add"]
+trait Add<RHS=Self> {
+    type Output;
+
+    fn add(self, RHS) -> Self::Output;
+}
+
+fn ice<A>(a: A) {
+    let r = loop {};
+    r = r + a; // here the type `r` is not yet inferred, hence `r+a` generates an error.
+    //~^ ERROR type of this value must be known
+}
diff --git a/src/test/compile-fail/bind-by-move-no-guards.rs b/src/test/compile-fail/bind-by-move-no-guards.rs
index 18534db0dd5..bb6060f2543 100644
--- a/src/test/compile-fail/bind-by-move-no-guards.rs
+++ b/src/test/compile-fail/bind-by-move-no-guards.rs
@@ -8,13 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
+
 fn main() {
     let (tx, rx) = channel();
     let x = Some(rx);
     tx.send(false);
     match x {
-        Some(z) if z.recv() => { panic!() }, //~ ERROR cannot bind by-move into a pattern guard
-        Some(z) => { assert!(!z.recv()); },
+        Some(z) if z.recv().unwrap() => { panic!() },
+            //~^ ERROR cannot bind by-move into a pattern guard
+        Some(z) => { assert!(!z.recv().unwrap()); },
         None => panic!()
     }
 }
diff --git a/src/test/compile-fail/binop-consume-args.rs b/src/test/compile-fail/binop-consume-args.rs
index 2bdd148b99b..afa255be699 100644
--- a/src/test/compile-fail/binop-consume-args.rs
+++ b/src/test/compile-fail/binop-consume-args.rs
@@ -10,6 +10,8 @@
 
 // Test that binary operators consume their arguments
 
+use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitXor, BitOr, Shl, Shr};
+
 fn add<A: Add<B, ()>, B>(lhs: A, rhs: B) {
     lhs + rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
diff --git a/src/test/compile-fail/binop-move-semantics.rs b/src/test/compile-fail/binop-move-semantics.rs
index d9440e18375..e48c88a49f0 100644
--- a/src/test/compile-fail/binop-move-semantics.rs
+++ b/src/test/compile-fail/binop-move-semantics.rs
@@ -10,6 +10,8 @@
 
 // Test that move restrictions are enforced on overloaded binary operations
 
+use std::ops::Add;
+
 fn double_move<T: Add<T, ()>>(x: T) {
     x
     +
diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs
index 05bc0d1e13b..7cd170f7773 100644
--- a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs
+++ b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs
@@ -11,19 +11,23 @@
 // Test how overloaded deref interacts with borrows when DerefMut
 // is implemented.
 
+#![feature(associated_types)]
+
 use std::ops::{Deref, DerefMut};
 
 struct Own<T> {
     value: *mut T
 }
 
-impl<T> Deref<T> for Own<T> {
+impl<T> Deref for Own<T> {
+    type Target = T;
+
     fn deref(&self) -> &T {
         unsafe { &*self.value }
     }
 }
 
-impl<T> DerefMut<T> for Own<T> {
+impl<T> DerefMut for Own<T> {
     fn deref_mut(&mut self) -> &mut T {
         unsafe { &mut *self.value }
     }
diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs
index 5aaefd01739..759467aeda3 100644
--- a/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs
+++ b/src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs
@@ -11,13 +11,17 @@
 // Test how overloaded deref interacts with borrows when only
 // Deref and not DerefMut is implemented.
 
+#![feature(associated_types)]
+
 use std::ops::Deref;
 
 struct Rc<T> {
     value: *const T
 }
 
-impl<T> Deref<T> for Rc<T> {
+impl<T> Deref for Rc<T> {
+    type Target = T;
+
     fn deref(&self) -> &T {
         unsafe { &*self.value }
     }
diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs b/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs
index 974fe3bc5d5..74dceab18ea 100644
--- a/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs
+++ b/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs
@@ -11,19 +11,23 @@
 // Test how overloaded deref interacts with borrows when DerefMut
 // is implemented.
 
+#![feature(associated_types)]
+
 use std::ops::{Deref, DerefMut};
 
 struct Own<T> {
     value: *mut T
 }
 
-impl<T> Deref<T> for Own<T> {
+impl<T> Deref for Own<T> {
+    type Target = T;
+
     fn deref<'a>(&'a self) -> &'a T {
         unsafe { &*self.value }
     }
 }
 
-impl<T> DerefMut<T> for Own<T> {
+impl<T> DerefMut for Own<T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         unsafe { &mut *self.value }
     }
diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs b/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs
index 5397c5b8a56..635e440c6fe 100644
--- a/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs
+++ b/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs
@@ -11,13 +11,17 @@
 // Test how overloaded deref interacts with borrows when only
 // Deref and not DerefMut is implemented.
 
+#![feature(associated_types)]
+
 use std::ops::Deref;
 
 struct Rc<T> {
     value: *const T
 }
 
-impl<T> Deref<T> for Rc<T> {
+impl<T> Deref for Rc<T> {
+    type Target = T;
+
     fn deref<'a>(&'a self) -> &'a T {
         unsafe { &*self.value }
     }
diff --git a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
index 3317295f88f..bcbb1f08b89 100644
--- a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
+++ b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ops::Add;
 
 #[derive(Clone)]
 struct foo(Box<uint>);
diff --git a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
index 3143da99f48..a0edd078184 100644
--- a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
+++ b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ops::Add;
+
 #[derive(Copy)]
 struct Point {
     x: int,
diff --git a/src/test/compile-fail/borrowck-overloaded-index-2.rs b/src/test/compile-fail/borrowck-overloaded-index-2.rs
index d9d7a43d46c..01afe405d5e 100644
--- a/src/test/compile-fail/borrowck-overloaded-index-2.rs
+++ b/src/test/compile-fail/borrowck-overloaded-index-2.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ops::Index;
+
 struct MyVec<T> {
     data: Vec<T>,
 }
diff --git a/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs b/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
index 2253d7512c0..e8949d4b30b 100644
--- a/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
+++ b/src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
@@ -11,6 +11,8 @@
 // Test that we still see borrowck errors of various kinds when using
 // indexing and autoderef in combination.
 
+use std::ops::{Index, IndexMut};
+
 struct Foo {
     x: int,
     y: int,
diff --git a/src/test/compile-fail/borrowck-overloaded-index.rs b/src/test/compile-fail/borrowck-overloaded-index.rs
index 0422f6381dc..933d0f15e4e 100644
--- a/src/test/compile-fail/borrowck-overloaded-index.rs
+++ b/src/test/compile-fail/borrowck-overloaded-index.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ops::{Index, IndexMut};
+
 struct Foo {
     x: int,
     y: int,
diff --git a/src/test/compile-fail/builtin-superkinds-self-type.rs b/src/test/compile-fail/builtin-superkinds-self-type.rs
index 4c7ff60fbdd..9826a5a0126 100644
--- a/src/test/compile-fail/builtin-superkinds-self-type.rs
+++ b/src/test/compile-fail/builtin-superkinds-self-type.rs
@@ -11,6 +11,8 @@
 // Tests (negatively) the ability for the Self type in default methods
 // to use capabilities granted by builtin kinds as supertraits.
 
+use std::sync::mpsc::{channel, Sender};
+
 trait Foo : Sync+'static {
     fn foo(self, mut chan: Sender<Self>) { }
 }
diff --git a/src/test/compile-fail/coherence-all-remote.rs b/src/test/compile-fail/coherence-all-remote.rs
new file mode 100644
index 00000000000..67d96aa95a6
--- /dev/null
+++ b/src/test/compile-fail/coherence-all-remote.rs
@@ -0,0 +1,19 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote;
+
+impl<T> Remote for int { }
+//~^ ERROR cannot provide an extension implementation
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence-bigint-param.rs b/src/test/compile-fail/coherence-bigint-param.rs
new file mode 100644
index 00000000000..a04dfd36c98
--- /dev/null
+++ b/src/test/compile-fail/coherence-bigint-param.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+pub struct BigInt;
+
+impl<T> Remote1<BigInt> for T { }
+//~^ ERROR type parameter `T` must also appear
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence-iterator-vec-any-elem.rs b/src/test/compile-fail/coherence-iterator-vec-any-elem.rs
new file mode 100644
index 00000000000..2ed7a6db7ae
--- /dev/null
+++ b/src/test/compile-fail/coherence-iterator-vec-any-elem.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+struct Foo<T>(T);
+
+impl<T,U> Remote1<U> for Foo<T> { }
+//~^ ERROR type parameter `U` must also appear
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence-lone-type-parameter.rs b/src/test/compile-fail/coherence-lone-type-parameter.rs
new file mode 100644
index 00000000000..0223dacd8ec
--- /dev/null
+++ b/src/test/compile-fail/coherence-lone-type-parameter.rs
@@ -0,0 +1,18 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote;
+
+impl<T> Remote for T { } //~ ERROR E0117
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence-overlapping-pairs.rs b/src/test/compile-fail/coherence-overlapping-pairs.rs
new file mode 100644
index 00000000000..d42bd529b66
--- /dev/null
+++ b/src/test/compile-fail/coherence-overlapping-pairs.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote;
+
+struct Foo;
+
+impl<T> Remote for lib::Pair<T,Foo> { }
+//~^ ERROR type parameter `T` must also appear
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence-pair-covered-uncovered.rs b/src/test/compile-fail/coherence-pair-covered-uncovered.rs
new file mode 100644
index 00000000000..09895ec11db
--- /dev/null
+++ b/src/test/compile-fail/coherence-pair-covered-uncovered.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::{Remote, Pair};
+
+struct Local<T>(T);
+
+impl<T,U> Remote for Pair<T,Local<U>> { }
+//~^ ERROR type parameter `T` must also appear
+
+fn main() { }
diff --git a/src/test/compile-fail/comm-not-freeze-receiver.rs b/src/test/compile-fail/comm-not-freeze-receiver.rs
index 8cb4b6328c4..2e535b39509 100644
--- a/src/test/compile-fail/comm-not-freeze-receiver.rs
+++ b/src/test/compile-fail/comm-not-freeze-receiver.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::Receiver;
+
 fn test<T: Sync>() {}
 
 fn main() {
diff --git a/src/test/compile-fail/comm-not-freeze.rs b/src/test/compile-fail/comm-not-freeze.rs
index 8c17895eb8a..1b1c43e4793 100644
--- a/src/test/compile-fail/comm-not-freeze.rs
+++ b/src/test/compile-fail/comm-not-freeze.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::Sender;
+
 fn test<T: Sync>() {}
 
 fn main() {
diff --git a/src/test/compile-fail/dst-sized-trait-param.rs b/src/test/compile-fail/dst-sized-trait-param.rs
index 750b475adb2..ea5becbf229 100644
--- a/src/test/compile-fail/dst-sized-trait-param.rs
+++ b/src/test/compile-fail/dst-sized-trait-param.rs
@@ -12,7 +12,7 @@
 // parameter, the corresponding value must be sized. Also that the
 // self type must be sized if appropriate.
 
-trait Foo<T> { fn take(self, x: &T) { } } // Note: T is sized
+trait Foo<T> : Sized { fn take(self, x: &T) { } } // Note: T is sized
 
 impl Foo<[int]> for uint { }
 //~^ ERROR the trait `core::kinds::Sized` is not implemented for the type `[int]`
diff --git a/src/test/compile-fail/infinite-autoderef.rs b/src/test/compile-fail/infinite-autoderef.rs
index e4c6fa7d47f..ab770c099e1 100644
--- a/src/test/compile-fail/infinite-autoderef.rs
+++ b/src/test/compile-fail/infinite-autoderef.rs
@@ -10,11 +10,15 @@
 
 // error-pattern: reached the recursion limit while auto-dereferencing
 
+#![feature(associated_types)]
+
 use std::ops::Deref;
 
 struct Foo;
 
-impl Deref<Foo> for Foo {
+impl Deref for Foo {
+    type Target = Foo;
+
     fn deref(&self) -> &Foo {
         self
     }
diff --git a/src/test/compile-fail/issue-12041.rs b/src/test/compile-fail/issue-12041.rs
index 1878b5f5dea..094f6d64edc 100644
--- a/src/test/compile-fail/issue-12041.rs
+++ b/src/test/compile-fail/issue-12041.rs
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
+use std::thread::Thread;
+
 fn main() {
     let (tx, rx) = channel();
-    spawn(move|| {
+    let _t = Thread::spawn(move|| -> () {
         loop {
             let tx = tx;
             //~^ ERROR: use of moved value: `tx`
diff --git a/src/test/compile-fail/issue-16709.rs b/src/test/compile-fail/issue-16709.rs
index fc15801eb75..327f50ee059 100644
--- a/src/test/compile-fail/issue-16709.rs
+++ b/src/test/compile-fail/issue-16709.rs
@@ -11,6 +11,8 @@
 use std::ptr;
 use std::raw;
 
+trait Slice {}
+
 fn main() {
   unsafe {
     let nil: *const u8 = ptr::null();
diff --git a/src/test/compile-fail/issue-18566.rs b/src/test/compile-fail/issue-18566.rs
index f64d8fee2d8..491707a9e31 100644
--- a/src/test/compile-fail/issue-18566.rs
+++ b/src/test/compile-fail/issue-18566.rs
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
+use std::ops::Deref;
+
 struct MyPtr<'a>(&'a mut uint);
-impl<'a> Deref<uint> for MyPtr<'a> {
+impl<'a> Deref for MyPtr<'a> {
+    type Target = uint;
+
     fn deref<'b>(&'b self) -> &'b uint { self.0 }
 }
 
diff --git a/src/test/run-fail/panic-non-utf8.rs b/src/test/compile-fail/issue-18819.rs
index 8b013199369..32a51ee065b 100644
--- a/src/test/run-fail/panic-non-utf8.rs
+++ b/src/test/compile-fail/issue-18819.rs
@@ -1,5 +1,4 @@
-
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -9,18 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Previously failed formating invalid utf8.
-// cc #16877
+#![feature(associated_types)]
+
+trait Foo {
+    type Item;
+}
+
+struct X;
 
-// error-pattern:panicked at 'hello�'
+impl Foo for X {
+    type Item = bool;
+}
 
-struct Foo;
-impl std::fmt::Show for Foo {
-    fn fmt(&self, fmtr:&mut std::fmt::Formatter) -> std::fmt::Result {
-        // Purge invalid utf8: 0xff
-        fmtr.write(&[104, 101, 108, 108, 111, 0xff])
-    }
+fn print_x(_: &Foo, extra: &str) {
+    println!("{}", extra);
 }
+
 fn main() {
-    panic!("{}", Foo)
+    print_x(X);  //~error this function takes 2 parameters but 1 parameter was supplied
 }
diff --git a/src/test/compile-fail/issue-18959.rs b/src/test/compile-fail/issue-18959.rs
index 3d126790335..1a792eb6e76 100644
--- a/src/test/compile-fail/issue-18959.rs
+++ b/src/test/compile-fail/issue-18959.rs
@@ -21,6 +21,6 @@ impl Foo for Thing {
 
 fn main() {
     let mut thing = Thing;
-    let test: &Bar = &mut thing; //~ ERROR cannot convert to a trait object because trait `Foo`
+    let test: &Bar = &mut thing; //~ ERROR cannot convert to a trait object
     foo(test);
 }
diff --git a/src/test/compile-fail/issue-19883.rs b/src/test/compile-fail/issue-19883.rs
new file mode 100644
index 00000000000..196a04db18a
--- /dev/null
+++ b/src/test/compile-fail/issue-19883.rs
@@ -0,0 +1,35 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_types)]
+
+trait From<Src> {
+    type Output;
+
+    fn from(src: Src) -> <Self as From<Src>>::Output;
+}
+
+trait To {
+    // This is a typo, the return type should be `<Dst as From<Self>>::Output`
+    fn to<Dst: From<Self>>(
+        self
+        //~^ error: the trait `core::kinds::Sized` is not implemented
+    ) ->
+        <Dst as From<Self>>::Dst
+        //~^ error: the trait `core::kinds::Sized` is not implemented
+    {
+        From::from(
+            //~^ error: the trait `core::kinds::Sized` is not implemented
+            self
+        )
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-20005.rs b/src/test/compile-fail/issue-20005.rs
new file mode 100644
index 00000000000..d9520583ca5
--- /dev/null
+++ b/src/test/compile-fail/issue-20005.rs
@@ -0,0 +1,29 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_types)]
+
+trait From<Src> {
+    type Result;
+
+    fn from(src: Src) -> Self::Result;
+}
+
+trait To {
+    fn to<Dst>(
+        self //~ error: the trait `core::kinds::Sized` is not implemented
+    ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
+        From::from( //~ error: the trait `core::kinds::Sized` is not implemented
+            self
+        )
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-20313.rs b/src/test/compile-fail/issue-20313.rs
new file mode 100644
index 00000000000..dfb23c05036
--- /dev/null
+++ b/src/test/compile-fail/issue-20313.rs
@@ -0,0 +1,17 @@
+// 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.
+
+extern {
+    #[link_name = "llvm.sqrt.f32"]
+    fn sqrt(x: f32) -> f32; //~ ERROR linking to LLVM intrinsics is experimental
+}
+
+fn main(){
+}
diff --git a/src/test/compile-fail/issue-3702-2.rs b/src/test/compile-fail/issue-3702-2.rs
index 54100d543dd..1e80fd7a7e9 100644
--- a/src/test/compile-fail/issue-3702-2.rs
+++ b/src/test/compile-fail/issue-3702-2.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::num::ToPrimitive;
+
 trait Add {
     fn to_int(&self) -> int;
     fn add_dynamic(&self, other: &Add) -> int;
diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs
index bbd41b28f03..f970cdb1b83 100644
--- a/src/test/compile-fail/issue-5543.rs
+++ b/src/test/compile-fail/issue-5543.rs
@@ -15,5 +15,4 @@ fn main() {
     let r: Box<Foo> = box 5;
     let _m: Box<Foo> = r as Box<Foo>;
     //~^ ERROR `core::kinds::Sized` is not implemented for the type `Foo`
-    //~| ERROR `Foo` is not implemented for the type `Foo`
 }
diff --git a/src/test/compile-fail/object-safety-by-value-self.rs b/src/test/compile-fail/object-safety-by-value-self.rs
new file mode 100644
index 00000000000..5ebcc8516ca
--- /dev/null
+++ b/src/test/compile-fail/object-safety-by-value-self.rs
@@ -0,0 +1,47 @@
+// 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.
+
+// Check that we correctly prevent users from making trait objects
+// from traits with a `fn(self)` method.
+
+trait Bar {
+    fn bar(self);
+}
+
+trait Baz {
+    fn baz(self: Self);
+}
+
+fn make_bar<T:Bar>(t: &T) -> &Bar {
+    t
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE method `bar` has a receiver type of `Self`
+}
+
+fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
+    t as &Bar
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE method `bar` has a receiver type of `Self`
+}
+
+fn make_baz<T:Baz>(t: &T) -> &Baz {
+    t
+        //~^ ERROR `Baz` is not object-safe
+        //~| NOTE method `baz` has a receiver type of `Self`
+}
+
+fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
+    t as &Baz
+        //~^ ERROR `Baz` is not object-safe
+        //~| NOTE method `baz` has a receiver type of `Self`
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-safety-generics.rs b/src/test/compile-fail/object-safety-generics.rs
new file mode 100644
index 00000000000..0ca706404c1
--- /dev/null
+++ b/src/test/compile-fail/object-safety-generics.rs
@@ -0,0 +1,31 @@
+// 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.
+
+// Check that we correctly prevent users from making trait objects
+// from traits with generic methods.
+
+trait Bar {
+    fn bar<T>(&self, t: T);
+}
+
+fn make_bar<T:Bar>(t: &T) -> &Bar {
+    t
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE method `bar` has generic type parameters
+}
+
+fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
+    t as &Bar
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE method `bar` has generic type parameters
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-safety-mentions-Self.rs b/src/test/compile-fail/object-safety-mentions-Self.rs
new file mode 100644
index 00000000000..df0f44c1391
--- /dev/null
+++ b/src/test/compile-fail/object-safety-mentions-Self.rs
@@ -0,0 +1,47 @@
+// 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.
+
+// Check that we correctly prevent users from making trait objects
+// form traits that make use of `Self` in an argument or return position.
+
+trait Bar {
+    fn bar(&self, x: &Self);
+}
+
+trait Baz {
+    fn bar(&self) -> Self;
+}
+
+fn make_bar<T:Bar>(t: &T) -> &Bar {
+    t
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE method `bar` references the `Self` type in its arguments or return type
+}
+
+fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
+    t as &Bar
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE method `bar` references the `Self` type in its arguments or return type
+}
+
+fn make_baz<T:Baz>(t: &T) -> &Baz {
+    t
+        //~^ ERROR `Baz` is not object-safe
+        //~| NOTE method `bar` references the `Self` type in its arguments or return type
+}
+
+fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
+    t as &Baz
+        //~^ ERROR `Baz` is not object-safe
+        //~| NOTE method `bar` references the `Self` type in its arguments or return type
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-safety-no-static.rs b/src/test/compile-fail/object-safety-no-static.rs
new file mode 100644
index 00000000000..6a010d49692
--- /dev/null
+++ b/src/test/compile-fail/object-safety-no-static.rs
@@ -0,0 +1,31 @@
+// 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.
+
+// Check that we correctly prevent users from making trait objects
+// from traits with static methods.
+
+trait Foo {
+    fn foo();
+}
+
+fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<Foo+'static> {
+    b
+        //~^ ERROR cannot convert to a trait object
+        //~| NOTE method `foo` has no receiver
+}
+
+fn foo_explicit<T:Foo+'static>(b: Box<T>) -> Box<Foo+'static> {
+    b as Box<Foo>
+        //~^ ERROR cannot convert to a trait object
+        //~| NOTE method `foo` has no receiver
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-safety-sized-2.rs b/src/test/compile-fail/object-safety-sized-2.rs
new file mode 100644
index 00000000000..3a02461bbb2
--- /dev/null
+++ b/src/test/compile-fail/object-safety-sized-2.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// Check that we correctly prevent users from making trait objects
+// from traits where `Self : Sized`.
+
+trait Bar
+    where Self : Sized
+{
+    fn bar<T>(&self, t: T);
+}
+
+fn make_bar<T:Bar>(t: &T) -> &Bar {
+    t
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE the trait cannot require that `Self : Sized`
+}
+
+fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
+    t as &Bar
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE the trait cannot require that `Self : Sized`
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/object-safety-sized.rs b/src/test/compile-fail/object-safety-sized.rs
new file mode 100644
index 00000000000..bc214f6f3d9
--- /dev/null
+++ b/src/test/compile-fail/object-safety-sized.rs
@@ -0,0 +1,31 @@
+// 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.
+
+// Check that we correctly prevent users from making trait objects
+// from traits where `Self : Sized`.
+
+trait Bar : Sized {
+    fn bar<T>(&self, t: T);
+}
+
+fn make_bar<T:Bar>(t: &T) -> &Bar {
+    t
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE the trait cannot require that `Self : Sized`
+}
+
+fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
+    t as &Bar
+        //~^ ERROR `Bar` is not object-safe
+        //~| NOTE the trait cannot require that `Self : Sized`
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/opt-out-copy-bad.rs b/src/test/compile-fail/opt-out-copy-bad.rs
index 80f8a154d58..4aae8fa87da 100644
--- a/src/test/compile-fail/opt-out-copy-bad.rs
+++ b/src/test/compile-fail/opt-out-copy-bad.rs
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 #![feature(opt_out_copy)]
+//~^ WARNING feature is deprecated
+//~| WARNING feature is deprecated
 
 // Test that when using the `opt-out-copy` feature we still consider
 // destructors to be non-movable
diff --git a/src/test/compile-fail/regions-infer-bound-from-trait-self.rs b/src/test/compile-fail/regions-infer-bound-from-trait-self.rs
index 25fd20b6ec5..aeb003ca5d0 100644
--- a/src/test/compile-fail/regions-infer-bound-from-trait-self.rs
+++ b/src/test/compile-fail/regions-infer-bound-from-trait-self.rs
@@ -23,12 +23,12 @@ fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { }
 
 // In these case, `Self` inherits `'static`.
 
-trait InheritsFromStatic : 'static {
+trait InheritsFromStatic : Sized + 'static {
     fn foo1<'a>(self, x: Inv<'a>) {
         check_bound(x, self)
     }
 }
-trait InheritsFromStaticIndirectly : Static {
+trait InheritsFromStaticIndirectly : Sized + Static {
     fn foo1<'a>(self, x: Inv<'a>) {
         check_bound(x, self)
     }
@@ -37,13 +37,13 @@ trait InheritsFromStaticIndirectly : Static {
 
 // In these case, `Self` inherits `'a`.
 
-trait InheritsFromIs<'a> : 'a {
+trait InheritsFromIs<'a> : Sized + 'a {
     fn foo(self, x: Inv<'a>) {
         check_bound(x, self)
     }
 }
 
-trait InheritsFromIsIndirectly<'a> : Is<'a> {
+trait InheritsFromIsIndirectly<'a> : Sized + Is<'a> {
     fn foo(self, x: Inv<'a>) {
         check_bound(x, self)
     }
@@ -51,7 +51,7 @@ trait InheritsFromIsIndirectly<'a> : Is<'a> {
 
 // In this case, `Self` inherits nothing.
 
-trait InheritsFromNothing<'a> {
+trait InheritsFromNothing<'a> : Sized {
     fn foo(self, x: Inv<'a>) {
         check_bound(x, self)
             //~^ ERROR parameter type `Self` may not live long enough
diff --git a/src/test/compile-fail/std-uncopyable-atomics.rs b/src/test/compile-fail/std-uncopyable-atomics.rs
index c0122b8a2a9..501187ca9e5 100644
--- a/src/test/compile-fail/std-uncopyable-atomics.rs
+++ b/src/test/compile-fail/std-uncopyable-atomics.rs
@@ -16,11 +16,11 @@ use std::sync::atomic::*;
 use std::ptr;
 
 fn main() {
-    let x = INIT_ATOMIC_BOOL;
+    let x = ATOMIC_BOOL_INIT;
     let x = *&x; //~ ERROR: cannot move out of dereference
-    let x = INIT_ATOMIC_INT;
+    let x = ATOMIC_INT_INIT;
     let x = *&x; //~ ERROR: cannot move out of dereference
-    let x = INIT_ATOMIC_UINT;
+    let x = ATOMIC_UINT_INIT;
     let x = *&x; //~ ERROR: cannot move out of dereference
     let x: AtomicPtr<uint> = AtomicPtr::new(ptr::null_mut());
     let x = *&x; //~ ERROR: cannot move out of dereference
diff --git a/src/test/compile-fail/trait-matching-lifetimes.rs b/src/test/compile-fail/trait-matching-lifetimes.rs
index f1b30166b5e..333730e0c4b 100644
--- a/src/test/compile-fail/trait-matching-lifetimes.rs
+++ b/src/test/compile-fail/trait-matching-lifetimes.rs
@@ -16,7 +16,7 @@ struct Foo<'a,'b> {
     y: &'b int,
 }
 
-trait Tr {
+trait Tr : Sized {
     fn foo(x: Self) {}
 }
 
diff --git a/src/test/compile-fail/trait-objects.rs b/src/test/compile-fail/trait-objects.rs
deleted file mode 100644
index 88b907a5cb9..00000000000
--- a/src/test/compile-fail/trait-objects.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-trait Foo {
-    fn foo(self);
-}
-
-trait Bar {
-    fn bar(&self, x: &Self);
-}
-
-trait Baz {
-    fn baz<T>(&self, x: &T);
-}
-
-impl Foo for int {
-    fn foo(self) {}
-}
-
-impl Bar for int {
-    fn bar(&self, _x: &int) {}
-}
-
-impl Baz for int {
-    fn baz<T>(&self, _x: &T) {}
-}
-
-fn main() {
-    let _: &Foo = &42i; //~ ERROR cannot convert to a trait object
-    let _: &Bar = &42i; //~ ERROR cannot convert to a trait object
-    let _: &Baz = &42i; //~ ERROR cannot convert to a trait object
-
-    let _ = &42i as &Foo; //~ ERROR cannot convert to a trait object
-    let _ = &42i as &Bar; //~ ERROR cannot convert to a trait object
-    let _ = &42i as &Baz; //~ ERROR cannot convert to a trait object
-}
diff --git a/src/test/compile-fail/trait-safety-fn-body.rs b/src/test/compile-fail/trait-safety-fn-body.rs
index d174092e4d0..f894e2ee28e 100644
--- a/src/test/compile-fail/trait-safety-fn-body.rs
+++ b/src/test/compile-fail/trait-safety-fn-body.rs
@@ -11,7 +11,7 @@
 // Check that an unsafe impl does not imply that unsafe actions are
 // legal in the methods.
 
-unsafe trait UnsafeTrait {
+unsafe trait UnsafeTrait : Sized {
     fn foo(self) { }
 }
 
diff --git a/src/test/compile-fail/type-params-in-different-spaces-2.rs b/src/test/compile-fail/type-params-in-different-spaces-2.rs
index 9be64bf5346..3a4cc9e874e 100644
--- a/src/test/compile-fail/type-params-in-different-spaces-2.rs
+++ b/src/test/compile-fail/type-params-in-different-spaces-2.rs
@@ -11,7 +11,7 @@
 // Test static calls to make sure that we align the Self and input
 // type parameters on a trait correctly.
 
-trait Tr<T> {
+trait Tr<T> : Sized {
     fn op(T) -> Self;
 }
 
diff --git a/src/test/compile-fail/type-params-in-different-spaces-3.rs b/src/test/compile-fail/type-params-in-different-spaces-3.rs
index a3d69d53ba9..c113e1b7815 100644
--- a/src/test/compile-fail/type-params-in-different-spaces-3.rs
+++ b/src/test/compile-fail/type-params-in-different-spaces-3.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Tr {
+trait Tr : Sized {
     fn test<X>(u: X) -> Self {
         u   //~ ERROR mismatched types
     }
diff --git a/src/test/compile-fail/unop-move-semantics.rs b/src/test/compile-fail/unop-move-semantics.rs
index ccdc7b833e7..c458c539c07 100644
--- a/src/test/compile-fail/unop-move-semantics.rs
+++ b/src/test/compile-fail/unop-move-semantics.rs
@@ -10,6 +10,8 @@
 
 // Test that move restrictions are enforced on overloaded unary operations
 
+use std::ops::Not;
+
 fn move_then_borrow<T: Not<T> + Clone>(x: T) {
     !x;
 
diff --git a/src/test/compile-fail/unsendable-class.rs b/src/test/compile-fail/unsendable-class.rs
index cd5918e2f47..993df8e59f3 100644
--- a/src/test/compile-fail/unsendable-class.rs
+++ b/src/test/compile-fail/unsendable-class.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
 
 // Test that a class with an unsendable field can't be
 // sent
diff --git a/src/test/compile-fail/unsized4.rs b/src/test/compile-fail/unsized4.rs
index 0537fc1f94a..f9ece8e6843 100644
--- a/src/test/compile-fail/unsized4.rs
+++ b/src/test/compile-fail/unsized4.rs
@@ -10,8 +10,7 @@
 
 // Test that bounds are sized-compatible.
 
-trait T {}
-
+trait T : Sized {}
 fn f<Sized? Y: T>() {
 //~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type
 }
diff --git a/src/test/compile-fail/variance-trait-matching-2.rs b/src/test/compile-fail/variance-trait-matching-2.rs
index ed4fdc52572..cae7a4cefad 100644
--- a/src/test/compile-fail/variance-trait-matching-2.rs
+++ b/src/test/compile-fail/variance-trait-matching-2.rs
@@ -10,17 +10,17 @@
 
 extern crate serialize;
 
-use std::io;
+use std::fmt;
 use serialize::{Encodable, Encoder};
 
 pub fn buffer_encode<'a,
-                     T:Encodable<serialize::json::Encoder<'a>,io::IoError>>(
+                     T:Encodable<serialize::json::Encoder<'a>,fmt::Error>>(
                      to_encode_object: &T)
-                     -> Vec<u8> {
-    let mut m = Vec::new();
+                     -> String {
+    let mut m = String::new();
     {
         let mut encoder =
-            serialize::json::Encoder::new(&mut m as &mut io::Writer);
+            serialize::json::Encoder::new(&mut m);
         //~^ ERROR `m` does not live long enough
         to_encode_object.encode(&mut encoder);
     }
diff --git a/src/test/compile-fail/wrong-mul-method-signature.rs b/src/test/compile-fail/wrong-mul-method-signature.rs
index b5e4cac7555..bde5b853078 100644
--- a/src/test/compile-fail/wrong-mul-method-signature.rs
+++ b/src/test/compile-fail/wrong-mul-method-signature.rs
@@ -13,6 +13,8 @@
 // (In this case the mul method should take &f64 and not f64)
 // See: #11450
 
+use std::ops::Mul;
+
 struct Vec1 {
     x: f64
 }
diff --git a/src/test/debuginfo/issue7712.rs b/src/test/debuginfo/issue7712.rs
index 948048ec272..94458a7fb4b 100644
--- a/src/test/debuginfo/issue7712.rs
+++ b/src/test/debuginfo/issue7712.rs
@@ -11,7 +11,7 @@
 // compile-flags:--debuginfo=1
 // min-lldb-version: 310
 
-pub trait TraitWithDefaultMethod {
+pub trait TraitWithDefaultMethod : Sized {
     fn method(self) {
         ()
     }
diff --git a/src/test/debuginfo/self-in-default-method.rs b/src/test/debuginfo/self-in-default-method.rs
index f8ef5b3d2fc..87884d2f956 100644
--- a/src/test/debuginfo/self-in-default-method.rs
+++ b/src/test/debuginfo/self-in-default-method.rs
@@ -118,7 +118,7 @@ struct Struct {
     x: int
 }
 
-trait Trait {
+trait Trait : Sized {
     fn self_by_ref(&self, arg1: int, arg2: int) -> int {
         zzz(); // #break
         arg1 + arg2
diff --git a/src/test/debuginfo/self-in-generic-default-method.rs b/src/test/debuginfo/self-in-generic-default-method.rs
index c2594df7d35..62b5e6872ee 100644
--- a/src/test/debuginfo/self-in-generic-default-method.rs
+++ b/src/test/debuginfo/self-in-generic-default-method.rs
@@ -118,7 +118,7 @@ struct Struct {
     x: int
 }
 
-trait Trait {
+trait Trait : Sized {
 
     fn self_by_ref<T>(&self, arg1: int, arg2: T) -> int {
         zzz(); // #break
diff --git a/src/test/debuginfo/unreachable-locals.rs b/src/test/debuginfo/unreachable-locals.rs
new file mode 100644
index 00000000000..c15dcd1958f
--- /dev/null
+++ b/src/test/debuginfo/unreachable-locals.rs
@@ -0,0 +1,86 @@
+// Copyright 2013-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-android: FIXME(#10381)
+// min-lldb-version: 310
+
+// compile-flags:-g
+
+#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
+
+// No need to actually run the debugger, just make sure that the compiler can
+// handle locals in unreachable code.
+
+fn after_return() {
+    return;
+    let x = "0";
+    let (ref y,z) = (1i32, 2u32);
+    match (20i32, 'c') {
+        (a, ref b) => {}
+    }
+    for a in [111i32].iter() {}
+}
+
+fn after_panic() {
+    panic!();
+    let x = "0";
+    let (ref y,z) = (1i32, 2u32);
+    match (20i32, 'c') {
+        (a, ref b) => {}
+    }
+    for a in [111i32].iter() {}
+}
+
+fn after_diverging_function() {
+    diverge();
+    let x = "0";
+    let (ref y,z) = (1i32, 2u32);
+    match (20i32, 'c') {
+        (a, ref b) => {}
+    }
+    for a in [111i32].iter() {}
+}
+
+fn after_break() {
+    loop {
+        break;
+        let x = "0";
+        let (ref y,z) = (1i32, 2u32);
+        match (20i32, 'c') {
+            (a, ref b) => {}
+        }
+        for a in [111i32].iter() {}
+    }
+}
+
+fn after_continue() {
+    for _ in range(0, 10i32) {
+        break;
+        let x = "0";
+        let (ref y,z) = (1i32, 2u32);
+        match (20i32, 'c') {
+            (a, ref b) => {}
+        }
+        for a in [111i32].iter() {}
+    }
+}
+
+fn main() {
+    after_return();
+    after_panic();
+    after_diverging_function();
+    after_break();
+    after_continue();
+}
+
+fn diverge() -> ! {
+    panic!();
+}
diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp
index c2ebd764ad6..35bd22880ce 100644
--- a/src/test/pretty/issue-4264.pp
+++ b/src/test/pretty/issue-4264.pp
@@ -4,7 +4,7 @@
 #[phase(plugin, link)]
 extern crate "std" as std;
 #[prelude_import]
-use std::prelude::*;
+use std::prelude::v1::*;
 // 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.
diff --git a/src/test/run-pass/issue-7320.rs b/src/test/pretty/let.rs
index c7087f8e3a8..736ea3a0d10 100644
--- a/src/test/run-pass/issue-7320.rs
+++ b/src/test/pretty/let.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pp-exact
 
-trait Foo {
-    fn foo(self: Box<Self>) { bar(self as Box<Foo>); }
-}
+// Check that `let x: _ = 0;` does not print as `let x = 0;`.
 
-fn bar(_b: Box<Foo>) { }
+fn main() {
+    let x: _ = 0;
 
-fn main() {}
+    let _ = x;
+}
diff --git a/src/test/run-make/compiler-lookup-paths/Makefile b/src/test/run-make/compiler-lookup-paths/Makefile
index 032e0882ff8..154e46c0edc 100644
--- a/src/test/run-make/compiler-lookup-paths/Makefile
+++ b/src/test/run-make/compiler-lookup-paths/Makefile
@@ -6,25 +6,25 @@ all: $(TMPDIR)/libnative.a
 	mv $(TMPDIR)/libnative.a $(TMPDIR)/native
 	$(RUSTC) a.rs
 	mv $(TMPDIR)/liba.rlib $(TMPDIR)/crate
-	$(RUSTC) b.rs -L $(TMPDIR)/crate:native && exit 1 || exit 0
-	$(RUSTC) b.rs -L $(TMPDIR)/crate:dependency && exit 1 || exit 0
-	$(RUSTC) b.rs -L $(TMPDIR)/crate:crate
-	$(RUSTC) b.rs -L $(TMPDIR)/crate
-	$(RUSTC) c.rs -L $(TMPDIR)/crate:native && exit 1 || exit 0
-	$(RUSTC) c.rs -L $(TMPDIR)/crate:crate && exit 1 || exit 0
-	$(RUSTC) c.rs -L $(TMPDIR)/crate:dependency
-	$(RUSTC) c.rs -L $(TMPDIR)/crate
-	$(RUSTC) d.rs -L $(TMPDIR)/native:dependency && exit 1 || exit 0
-	$(RUSTC) d.rs -L $(TMPDIR)/native:crate && exit 1 || exit 0
-	$(RUSTC) d.rs -L $(TMPDIR)/native:native
-	$(RUSTC) d.rs -L $(TMPDIR)/native
+	$(RUSTC) b.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0
+	$(RUSTC) b.rs -L dependency=$(TMPDIR)/crate && exit 1 || exit 0
+	$(RUSTC) b.rs -L crate=$(TMPDIR)/crate
+	$(RUSTC) b.rs -L all=$(TMPDIR)/crate
+	$(RUSTC) c.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0
+	$(RUSTC) c.rs -L crate=$(TMPDIR)/crate && exit 1 || exit 0
+	$(RUSTC) c.rs -L dependency=$(TMPDIR)/crate
+	$(RUSTC) c.rs -L all=$(TMPDIR)/crate
+	$(RUSTC) d.rs -L dependency=$(TMPDIR)/native && exit 1 || exit 0
+	$(RUSTC) d.rs -L crate=$(TMPDIR)/native && exit 1 || exit 0
+	$(RUSTC) d.rs -L native=$(TMPDIR)/native
+	$(RUSTC) d.rs -L all=$(TMPDIR)/native
 	mkdir -p $(TMPDIR)/e1
 	mkdir -p $(TMPDIR)/e2
 	$(RUSTC) e.rs -o $(TMPDIR)/e1/libe.rlib
 	$(RUSTC) e.rs -o $(TMPDIR)/e2/libe.rlib
 	$(RUSTC) f.rs -L $(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0
-	$(RUSTC) f.rs -L $(TMPDIR)/e1:crate -L $(TMPDIR)/e2 && exit 1 || exit 0
-	$(RUSTC) f.rs -L $(TMPDIR)/e1:crate -L $(TMPDIR)/e2:crate && exit 1 || exit 0
-	$(RUSTC) f.rs -L $(TMPDIR)/e1:native -L $(TMPDIR)/e2
-	$(RUSTC) f.rs -L $(TMPDIR)/e1:dependency -L $(TMPDIR)/e2
-	$(RUSTC) f.rs -L $(TMPDIR)/e1:dependency -L $(TMPDIR)/e2:crate
+	$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0
+	$(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2 && exit 1 || exit 0
+	$(RUSTC) f.rs -L native=$(TMPDIR)/e1 -L $(TMPDIR)/e2
+	$(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L $(TMPDIR)/e2
+	$(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2
diff --git a/src/test/run-make/manual-link/Makefile b/src/test/run-make/manual-link/Makefile
index d2a02adc9d4..d0536956152 100644
--- a/src/test/run-make/manual-link/Makefile
+++ b/src/test/run-make/manual-link/Makefile
@@ -1,7 +1,7 @@
 -include ../tools.mk
 
 all: $(TMPDIR)/libbar.a
-	$(RUSTC) foo.rs -lbar:static
+	$(RUSTC) foo.rs -lstatic=bar
 	$(RUSTC) main.rs
 	$(call RUN,main)
 
diff --git a/src/test/run-pass/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types-conditional-dispatch.rs
new file mode 100644
index 00000000000..3b53203d218
--- /dev/null
+++ b/src/test/run-pass/associated-types-conditional-dispatch.rs
@@ -0,0 +1,73 @@
+// 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.
+
+// Test that we evaluate projection predicates to winnow out
+// candidates during trait selection and method resolution (#20296).
+// If we don't properly winnow out candidates based on the output type
+// `Target=[A]`, then the impl marked with `(*)` is seen to conflict
+// with all the others.
+
+#![feature(associated_types, default_type_params)]
+
+use std::ops::Deref;
+
+pub trait MyEq<Sized? U=Self> for Sized? {
+    fn eq(&self, u: &U) -> bool;
+}
+
+impl<A, B> MyEq<[B]> for [A]
+    where A : MyEq<B>
+{
+    fn eq(&self, other: &[B]) -> bool {
+        self.len() == other.len() &&
+            self.iter().zip(other.iter())
+                       .all(|(a, b)| MyEq::eq(a, b))
+    }
+}
+
+// (*) This impl conflicts with everything unless the `Target=[A]`
+// constraint is considered.
+impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs
+    where A: MyEq<B>, Lhs: Deref<Target=[A]>
+{
+    fn eq(&self, other: &[B; 0]) -> bool {
+        MyEq::eq(&**self, other.as_slice())
+    }
+}
+
+struct DerefWithHelper<H, T> {
+    pub helper: H
+}
+
+trait Helper<T> {
+    fn helper_borrow(&self) -> &T;
+}
+
+impl<T> Helper<T> for Option<T> {
+    fn helper_borrow(&self) -> &T {
+        self.as_ref().unwrap()
+    }
+}
+
+impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        self.helper.helper_borrow()
+    }
+}
+
+pub fn check<T: MyEq>(x: T, y: T) -> bool {
+    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
+    d.eq(&y)
+}
+
+pub fn main() {
+}
diff --git a/src/test/run-pass/associated-types-impl-redirect.rs b/src/test/run-pass/associated-types-impl-redirect.rs
index a28cf346336..ce7f5dde2ad 100644
--- a/src/test/run-pass/associated-types-impl-redirect.rs
+++ b/src/test/run-pass/associated-types-impl-redirect.rs
@@ -19,6 +19,7 @@
 #![feature(associated_types, lang_items, unboxed_closures)]
 #![no_implicit_prelude]
 
+use std::kinds::Sized;
 use std::option::Option::{None, Some, mod};
 
 trait Iterator {
@@ -27,7 +28,7 @@ trait Iterator {
     fn next(&mut self) -> Option<Self::Item>;
 }
 
-trait IteratorExt: Iterator {
+trait IteratorExt: Iterator + Sized {
     fn by_ref(&mut self) -> ByRef<Self> {
         ByRef(self)
     }
diff --git a/src/test/run-pass/associated-types-projection-bound-in-supertraits.rs b/src/test/run-pass/associated-types-projection-bound-in-supertraits.rs
index 83686d92a7c..92daee5225d 100644
--- a/src/test/run-pass/associated-types-projection-bound-in-supertraits.rs
+++ b/src/test/run-pass/associated-types-projection-bound-in-supertraits.rs
@@ -21,7 +21,7 @@ trait Not {
     fn not(self) -> Self::Result;
 }
 
-trait Int: Not<Result=Self> {
+trait Int: Not<Result=Self> + Sized {
     fn count_ones(self) -> uint;
     fn count_zeros(self) -> uint {
         // neither works
diff --git a/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs b/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs
index 062d37556ec..7afaf290424 100644
--- a/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs
+++ b/src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs
@@ -19,6 +19,7 @@
 #![feature(associated_types, lang_items, unboxed_closures)]
 #![no_implicit_prelude]
 
+use std::kinds::Sized;
 use std::option::Option::{None, Some, mod};
 
 trait Iterator {
@@ -27,7 +28,7 @@ trait Iterator {
     fn next(&mut self) -> Option<Self::Item>;
 }
 
-trait IteratorExt: Iterator {
+trait IteratorExt: Iterator + Sized {
     fn by_ref(&mut self) -> ByRef<Self> {
         ByRef(self)
     }
diff --git a/src/test/run-pass/bool.rs b/src/test/run-pass/bool.rs
index 238d0ecdca7..b3c4802530e 100644
--- a/src/test/run-pass/bool.rs
+++ b/src/test/run-pass/bool.rs
@@ -10,6 +10,9 @@
 
 // Basic boolean tests
 
+use std::cmp::Ordering::{Equal, Greater, Less};
+use std::ops::{BitAnd, BitOr, BitXor};
+
 fn main() {
     assert_eq!(false.eq(&true), false);
     assert_eq!(false == false, true);
diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/run-pass/bug-7183-generics.rs
index 8c4d10a2d59..bf8d303f341 100644
--- a/src/test/run-pass/bug-7183-generics.rs
+++ b/src/test/run-pass/bug-7183-generics.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Speak {
+trait Speak : Sized {
     fn say(&self, s:&str) -> String;
     fn hi(&self) -> String { hello(self) }
 }
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
index 2abc58d8a49..365670db6f9 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
@@ -14,6 +14,8 @@
 // a Send. Basically this just makes sure rustc is using
 // each_bound_trait_and_supertraits in type_contents correctly.
 
+use std::sync::mpsc::{channel, Sender};
+
 trait Bar : Send { }
 trait Foo : Bar { }
 
@@ -21,11 +23,11 @@ impl <T: Send> Foo for T { }
 impl <T: Send> Bar for T { }
 
 fn foo<T: Foo>(val: T, chan: Sender<T>) {
-    chan.send(val);
+    chan.send(val).unwrap();
 }
 
 pub fn main() {
     let (tx, rx) = channel();
     foo(31337i, tx);
-    assert!(rx.recv() == 31337i);
+    assert!(rx.recv().unwrap() == 31337i);
 }
diff --git a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
index efea4ffe9be..126088d7f9d 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities-xc.rs
@@ -15,6 +15,8 @@
 // even when using them cross-crate.
 
 extern crate trait_superkinds_in_metadata;
+
+use std::sync::mpsc::{channel, Sender, Receiver};
 use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
 
 #[derive(PartialEq)]
@@ -24,11 +26,11 @@ impl <T: Sync> RequiresShare for X<T> { }
 impl <T: Sync+Send> RequiresRequiresShareAndSend for X<T> { }
 
 fn foo<T: RequiresRequiresShareAndSend>(val: T, chan: Sender<T>) {
-    chan.send(val);
+    chan.send(val).unwrap();
 }
 
 pub fn main() {
     let (tx, rx): (Sender<X<int>>, Receiver<X<int>>) = channel();
     foo(X(31337i), tx);
-    assert!(rx.recv() == X(31337i));
+    assert!(rx.recv().unwrap() == X(31337i));
 }
diff --git a/src/test/run-pass/builtin-superkinds-capabilities.rs b/src/test/run-pass/builtin-superkinds-capabilities.rs
index fb3e1b02728..7f4a2398f54 100644
--- a/src/test/run-pass/builtin-superkinds-capabilities.rs
+++ b/src/test/run-pass/builtin-superkinds-capabilities.rs
@@ -12,16 +12,18 @@
 // builtin-kinds, e.g., if a trait requires Send to implement, then
 // at usage site of that trait, we know we have the Send capability.
 
+use std::sync::mpsc::{channel, Sender, Receiver};
+
 trait Foo : Send { }
 
 impl <T: Send> Foo for T { }
 
 fn foo<T: Foo>(val: T, chan: Sender<T>) {
-    chan.send(val);
+    chan.send(val).unwrap();
 }
 
 pub fn main() {
     let (tx, rx): (Sender<int>, Receiver<int>) = channel();
     foo(31337i, tx);
-    assert!(rx.recv() == 31337i);
+    assert!(rx.recv().unwrap() == 31337i);
 }
diff --git a/src/test/run-pass/builtin-superkinds-self-type.rs b/src/test/run-pass/builtin-superkinds-self-type.rs
index 1c156f6551c..d0db2542ccc 100644
--- a/src/test/run-pass/builtin-superkinds-self-type.rs
+++ b/src/test/run-pass/builtin-superkinds-self-type.rs
@@ -11,9 +11,11 @@
 // Tests the ability for the Self type in default methods to use
 // capabilities granted by builtin kinds as supertraits.
 
-trait Foo : Send {
+use std::sync::mpsc::{Sender, channel};
+
+trait Foo : Send + Sized {
     fn foo(self, tx: Sender<Self>) {
-        tx.send(self);
+        tx.send(self).unwrap();
     }
 }
 
@@ -22,5 +24,5 @@ impl <T: Send> Foo for T { }
 pub fn main() {
     let (tx, rx) = channel();
     1193182i.foo(tx);
-    assert!(rx.recv() == 1193182i);
+    assert!(rx.recv().unwrap() == 1193182i);
 }
diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs
index 597e067b8b6..c95cf0bfdee 100644
--- a/src/test/run-pass/c-stack-returning-int64.rs
+++ b/src/test/run-pass/c-stack-returning-int64.rs
@@ -12,6 +12,8 @@
 
 extern crate libc;
 
+use std::c_str::ToCStr;
+
 mod mlibc {
     use libc::{c_char, c_long, c_longlong};
 
diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs
index f2df5ef38c3..3f6d6a02c79 100644
--- a/src/test/run-pass/capturing-logging.rs
+++ b/src/test/run-pass/capturing-logging.rs
@@ -17,8 +17,10 @@
 extern crate log;
 
 use log::{set_logger, Logger, LogRecord};
+use std::sync::mpsc::channel;
 use std::fmt;
 use std::io::{ChanReader, ChanWriter};
+use std::thread::Thread;
 
 struct MyWriter(ChanWriter);
 
@@ -32,7 +34,7 @@ impl Logger for MyWriter {
 fn main() {
     let (tx, rx) = channel();
     let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-    spawn(move|| {
+    let _t = Thread::spawn(move|| {
         set_logger(box MyWriter(w) as Box<Logger+Send>);
         debug!("debug");
         info!("info");
diff --git a/src/test/run-pass/cci_capture_clause.rs b/src/test/run-pass/cci_capture_clause.rs
index c4bf8131506..8b2947ba3ee 100644
--- a/src/test/run-pass/cci_capture_clause.rs
+++ b/src/test/run-pass/cci_capture_clause.rs
@@ -16,5 +16,5 @@
 extern crate cci_capture_clause;
 
 pub fn main() {
-    cci_capture_clause::foo(()).recv()
+    cci_capture_clause::foo(()).recv().unwrap();
 }
diff --git a/src/test/run-pass/closure-bounds-can-capture-chan.rs b/src/test/run-pass/closure-bounds-can-capture-chan.rs
index cdcdad47ea4..816b28c3a9a 100644
--- a/src/test/run-pass/closure-bounds-can-capture-chan.rs
+++ b/src/test/run-pass/closure-bounds-can-capture-chan.rs
@@ -10,7 +10,7 @@
 
 #![feature(unboxed_closures)]
 
-use std::comm;
+use std::sync::mpsc::channel;
 
 fn foo<F:FnOnce()+Send>(blk: F) {
     blk();
@@ -19,7 +19,7 @@ fn foo<F:FnOnce()+Send>(blk: F) {
 pub fn main() {
     let (tx, rx) = channel();
     foo(move || {
-        tx.send(());
+        tx.send(()).unwrap();
     });
-    rx.recv();
+    rx.recv().unwrap();
 }
diff --git a/src/test/run-pass/cmp-default.rs b/src/test/run-pass/cmp-default.rs
index cfba87c3f69..fd040d10910 100644
--- a/src/test/run-pass/cmp-default.rs
+++ b/src/test/run-pass/cmp-default.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::cmp::Ordering;
+
 // Test default methods in PartialOrd and PartialEq
 //
 struct Fool(bool);
diff --git a/src/test/run-pass/coherence-bigint-int.rs b/src/test/run-pass/coherence-bigint-int.rs
new file mode 100644
index 00000000000..1e90453980f
--- /dev/null
+++ b/src/test/run-pass/coherence-bigint-int.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+pub struct BigInt;
+
+impl Remote1<BigInt> for int { }
+
+fn main() { }
diff --git a/src/test/run-pass/coherence-bigint-vecint.rs b/src/test/run-pass/coherence-bigint-vecint.rs
new file mode 100644
index 00000000000..b100455eb33
--- /dev/null
+++ b/src/test/run-pass/coherence-bigint-vecint.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+pub struct BigInt;
+
+impl Remote1<BigInt> for Vec<int> { }
+
+fn main() { }
diff --git a/src/test/run-pass/trait-object-safety.rs b/src/test/run-pass/coherence-blanket.rs
index ed7284a8353..e02117d1ca2 100644
--- a/src/test/run-pass/trait-object-safety.rs
+++ b/src/test/run-pass/coherence-blanket.rs
@@ -8,19 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Check that object-safe methods are identified as such.
+// aux-build:coherence-lib.rs
 
-trait Tr {
-    fn foo(&self);
-}
-
-struct St;
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
 
-impl Tr for St {
-    fn foo(&self) {}
+pub trait Local {
+    fn foo(&self) { }
 }
 
-fn main() {
-    let s: &Tr = &St;
-    s.foo();
-}
+impl<T> Local for T { }
+
+fn main() { }
diff --git a/src/test/run-pass/coherence-covered-type-parameter.rs b/src/test/run-pass/coherence-covered-type-parameter.rs
new file mode 100644
index 00000000000..27f1f2dafb0
--- /dev/null
+++ b/src/test/run-pass/coherence-covered-type-parameter.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote;
+
+struct Foo<T>(T);
+
+impl<T> Remote for Foo<T> { }
+
+fn main() { }
diff --git a/src/test/run-pass/coherence-iterator-vec.rs b/src/test/run-pass/coherence-iterator-vec.rs
new file mode 100644
index 00000000000..7077503f73f
--- /dev/null
+++ b/src/test/run-pass/coherence-iterator-vec.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+struct Foo<T>(T);
+
+impl<T> Remote1<T> for Foo<T> { }
+
+fn main() { }
diff --git a/src/test/run-pass/coherence-local-1.rs b/src/test/run-pass/coherence-local-1.rs
new file mode 100644
index 00000000000..a9bc3dc0e2f
--- /dev/null
+++ b/src/test/run-pass/coherence-local-1.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote;
+
+struct Local;
+
+impl Remote for Vec<Local> { }
+
+fn main() { }
diff --git a/src/test/run-pass/coherence-local-2.rs b/src/test/run-pass/coherence-local-2.rs
new file mode 100644
index 00000000000..07a830cb1ac
--- /dev/null
+++ b/src/test/run-pass/coherence-local-2.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote;
+
+struct Local<T>(T);
+
+impl<T> Remote for Vec<Local<T>> { }
+
+fn main() { }
diff --git a/src/test/run-pass/colorful-write-macros.rs b/src/test/run-pass/colorful-write-macros.rs
index bbb049eb960..d2caecdf05b 100644
--- a/src/test/run-pass/colorful-write-macros.rs
+++ b/src/test/run-pass/colorful-write-macros.rs
@@ -15,7 +15,6 @@
 
 use std::io::MemWriter;
 use std::fmt;
-use std::fmt::FormatWriter;
 
 struct Foo<'a> {
     writer: &'a mut (Writer+'a),
@@ -24,8 +23,8 @@ struct Foo<'a> {
 
 struct Bar;
 
-impl fmt::FormatWriter for Bar {
-    fn write(&mut self, _: &[u8]) -> fmt::Result {
+impl fmt::Writer for Bar {
+    fn write_str(&mut self, _: &str) -> fmt::Result {
         Ok(())
     }
 }
@@ -41,5 +40,8 @@ fn main() {
     println!("ok");
 
     let mut s = Bar;
-    write!(&mut s, "test");
+    {
+        use std::fmt::Writer;
+        write!(&mut s, "test");
+    }
 }
diff --git a/src/test/run-pass/comm.rs b/src/test/run-pass/comm.rs
index edd4d5642b5..5cfc692aae4 100644
--- a/src/test/run-pass/comm.rs
+++ b/src/test/run-pass/comm.rs
@@ -9,11 +9,12 @@
 // except according to those terms.
 
 use std::task;
+use std::sync::mpsc::{channel, Sender};
 
 pub fn main() {
     let (tx, rx) = channel();
     let _t = task::spawn(move|| { child(&tx) });
-    let y = rx.recv();
+    let y = rx.recv().unwrap();
     println!("received");
     println!("{}", y);
     assert_eq!(y, 10);
@@ -21,6 +22,6 @@ pub fn main() {
 
 fn child(c: &Sender<int>) {
     println!("sending");
-    c.send(10);
+    c.send(10).unwrap();
     println!("value sent");
 }
diff --git a/src/test/run-pass/const-str-ptr.rs b/src/test/run-pass/const-str-ptr.rs
index d6f0296619a..e0e8ca5618e 100644
--- a/src/test/run-pass/const-str-ptr.rs
+++ b/src/test/run-pass/const-str-ptr.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::{str, string};
+use std::c_str::ToCStr;
 
 const A: [u8; 2] = ['h' as u8, 'i' as u8];
 const B: &'static [u8; 2] = &A;
diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs
index a0fa2d178b9..c1db8a6eb13 100644
--- a/src/test/run-pass/core-run-destroy.rs
+++ b/src/test/run-pass/core-run-destroy.rs
@@ -23,6 +23,8 @@ extern crate libc;
 use std::io::{Process, Command, timer};
 use std::time::Duration;
 use std::str;
+use std::sync::mpsc::channel;
+use std::thread::Thread;
 
 macro_rules! succeed( ($e:expr) => (
     match $e { Ok(..) => {}, Err(e) => panic!("panic: {}", e) }
@@ -84,15 +86,15 @@ pub fn test_destroy_actually_kills(force: bool) {
     let (tx, rx1) = channel();
     let mut t = timer::Timer::new().unwrap();
     let rx2 = t.oneshot(Duration::milliseconds(1000));
-    spawn(move|| {
+    Thread::spawn(move|| {
         select! {
-            () = rx2.recv() => unsafe { libc::exit(1) },
-            () = rx1.recv() => {}
+            _ = rx2.recv() => unsafe { libc::exit(1) },
+            _ = rx1.recv() => {}
         }
-    });
+    }).detach();
     match p.wait().unwrap() {
         ExitStatus(..) => panic!("expected a signal"),
-        ExitSignal(..) => tx.send(()),
+        ExitSignal(..) => tx.send(()).unwrap(),
     }
 }
 
diff --git a/src/test/run-pass/default-method-supertrait-vtable.rs b/src/test/run-pass/default-method-supertrait-vtable.rs
index 1b2b17f9917..727cada21fa 100644
--- a/src/test/run-pass/default-method-supertrait-vtable.rs
+++ b/src/test/run-pass/default-method-supertrait-vtable.rs
@@ -21,7 +21,7 @@ trait Y {
 }
 
 
-trait Z: Y {
+trait Z: Y + Sized {
     fn x(self) -> int {
         require_y(self)
     }
diff --git a/src/test/run-pass/deref-mut-on-ref.rs b/src/test/run-pass/deref-mut-on-ref.rs
index dcf7c483b2c..f43be177862 100644
--- a/src/test/run-pass/deref-mut-on-ref.rs
+++ b/src/test/run-pass/deref-mut-on-ref.rs
@@ -10,7 +10,9 @@
 
 // Test that `&mut T` implements `DerefMut<T>`
 
-fn inc<T:DerefMut<int>>(mut t: T) {
+use std::ops::{Deref, DerefMut};
+
+fn inc<T: Deref<Target=int> + DerefMut>(mut t: T) {
     *t += 1;
 }
 
diff --git a/src/test/run-pass/deref-on-ref.rs b/src/test/run-pass/deref-on-ref.rs
index 27e7d8f3ba2..e95d942c8cf 100644
--- a/src/test/run-pass/deref-on-ref.rs
+++ b/src/test/run-pass/deref-on-ref.rs
@@ -10,7 +10,9 @@
 
 // Test that `&T` and `&mut T` implement `Deref<T>`
 
-fn deref<U:Copy,T:Deref<U>>(t: T) -> U {
+use std::ops::Deref;
+
+fn deref<U:Copy,T:Deref<Target=U>>(t: T) -> U {
     *t
 }
 
diff --git a/src/test/run-pass/deriving-cmp-shortcircuit.rs b/src/test/run-pass/deriving-cmp-shortcircuit.rs
index 0a139667c0e..bc55b9132c8 100644
--- a/src/test/run-pass/deriving-cmp-shortcircuit.rs
+++ b/src/test/run-pass/deriving-cmp-shortcircuit.rs
@@ -12,6 +12,8 @@
 // where possible, by having a type that panics when compared as the
 // second element, so this passes iff the instances shortcircuit.
 
+use std::cmp::Ordering;
+
 pub struct FailCmp;
 impl PartialEq for FailCmp {
     fn eq(&self, _: &FailCmp) -> bool { panic!("eq") }
diff --git a/src/test/run-pass/deriving-encodable-decodable-box.rs b/src/test/run-pass/deriving-encodable-decodable-box.rs
index b0c5d88c48e..b7be14321fd 100644
--- a/src/test/run-pass/deriving-encodable-decodable-box.rs
+++ b/src/test/run-pass/deriving-encodable-decodable-box.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(old_orphan_check)]
+
 extern crate serialize;
 
 use serialize::{Encodable, Decodable};
diff --git a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
index 1176cc303b7..3b2c1d9f27c 100644
--- a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
+++ b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
@@ -11,6 +11,8 @@
 // This briefly tests the capability of `Cell` and `RefCell` to implement the
 // `Encodable` and `Decodable` traits via `#[derive(Encodable, Decodable)]`
 
+#![feature(old_orphan_check)]
+
 extern crate serialize;
 
 use std::cell::{Cell, RefCell};
diff --git a/src/test/run-pass/deriving-global.rs b/src/test/run-pass/deriving-global.rs
index 80a6829986d..849733ecc1f 100644
--- a/src/test/run-pass/deriving-global.rs
+++ b/src/test/run-pass/deriving-global.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(old_orphan_check)]
+
 extern crate serialize;
 extern crate rand;
 
diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs
index 71f0acea0bf..a6c0a592c77 100644
--- a/src/test/run-pass/deriving-zero.rs
+++ b/src/test/run-pass/deriving-zero.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use std::ops::Add;
 use std::num::Zero;
 
 #[derive(Zero)]
diff --git a/src/test/run-pass/drop-trait-enum.rs b/src/test/run-pass/drop-trait-enum.rs
index 16ad2b8e21a..381404d2e21 100644
--- a/src/test/run-pass/drop-trait-enum.rs
+++ b/src/test/run-pass/drop-trait-enum.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::task;
+use std::sync::mpsc::{channel, Sender};
 
 #[derive(PartialEq, Show)]
 enum Message {
@@ -22,7 +23,7 @@ struct SendOnDrop {
 
 impl Drop for SendOnDrop {
     fn drop(&mut self) {
-        self.sender.send(Message::Dropped);
+        self.sender.send(Message::Dropped).unwrap();
     }
 }
 
@@ -36,10 +37,10 @@ impl Drop for Foo {
     fn drop(&mut self) {
         match self {
             &Foo::SimpleVariant(ref mut sender) => {
-                sender.send(Message::DestructorRan);
+                sender.send(Message::DestructorRan).unwrap();
             }
             &Foo::NestedVariant(_, _, ref mut sender) => {
-                sender.send(Message::DestructorRan);
+                sender.send(Message::DestructorRan).unwrap();
             }
             &Foo::FailingVariant { .. } => {
                 panic!("Failed");
@@ -53,23 +54,23 @@ pub fn main() {
     {
         let v = Foo::SimpleVariant(sender);
     }
-    assert_eq!(receiver.recv(), Message::DestructorRan);
-    assert_eq!(receiver.recv_opt().ok(), None);
+    assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
+    assert_eq!(receiver.recv().ok(), None);
 
     let (sender, receiver) = channel();
     {
         let v = Foo::NestedVariant(box 42u, SendOnDrop { sender: sender.clone() }, sender);
     }
-    assert_eq!(receiver.recv(), Message::DestructorRan);
-    assert_eq!(receiver.recv(), Message::Dropped);
-    assert_eq!(receiver.recv_opt().ok(), None);
+    assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
+    assert_eq!(receiver.recv().unwrap(), Message::Dropped);
+    assert_eq!(receiver.recv().ok(), None);
 
     let (sender, receiver) = channel();
     task::spawn(move|| {
         let v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } };
     });
-    assert_eq!(receiver.recv(), Message::Dropped);
-    assert_eq!(receiver.recv_opt().ok(), None);
+    assert_eq!(receiver.recv().unwrap(), Message::Dropped);
+    assert_eq!(receiver.recv().ok(), None);
 
     let (sender, receiver) = channel();
     {
@@ -82,11 +83,11 @@ pub fn main() {
             v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } };
         });
     }
-    assert_eq!(receiver.recv(), Message::DestructorRan);
-    assert_eq!(receiver.recv(), Message::Dropped);
-    assert_eq!(receiver.recv(), Message::DestructorRan);
-    assert_eq!(receiver.recv(), Message::Dropped);
-    assert_eq!(receiver.recv(), Message::DestructorRan);
-    assert_eq!(receiver.recv(), Message::Dropped);
-    assert_eq!(receiver.recv_opt().ok(), None);
+    assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
+    assert_eq!(receiver.recv().unwrap(), Message::Dropped);
+    assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
+    assert_eq!(receiver.recv().unwrap(), Message::Dropped);
+    assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
+    assert_eq!(receiver.recv().unwrap(), Message::Dropped);
+    assert_eq!(receiver.recv().ok(), None);
 }
diff --git a/src/test/run-pass/dst-deref-mut.rs b/src/test/run-pass/dst-deref-mut.rs
index c2707a1ae6e..0e0ed1f436c 100644
--- a/src/test/run-pass/dst-deref-mut.rs
+++ b/src/test/run-pass/dst-deref-mut.rs
@@ -10,17 +10,23 @@
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
+#![feature(associated_types)]
+
+use std::ops::{Deref, DerefMut};
+
 pub struct Arr {
     ptr: Box<[uint]>
 }
 
-impl Deref<[uint]> for Arr {
+impl Deref for Arr {
+    type Target = [uint];
+
     fn deref(&self) -> &[uint] {
         panic!();
     }
 }
 
-impl DerefMut<[uint]> for Arr {
+impl DerefMut for Arr {
     fn deref_mut(&mut self) -> &mut [uint] {
         &mut *self.ptr
     }
diff --git a/src/test/run-pass/dst-deref.rs b/src/test/run-pass/dst-deref.rs
index 43b7d116d30..a39670a27b9 100644
--- a/src/test/run-pass/dst-deref.rs
+++ b/src/test/run-pass/dst-deref.rs
@@ -10,11 +10,17 @@
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
+#![feature(associated_types)]
+
+use std::ops::Deref;
+
 pub struct Arr {
     ptr: Box<[uint]>
 }
 
-impl Deref<[uint]> for Arr {
+impl Deref for Arr {
+    type Target = [uint];
+
     fn deref(&self) -> &[uint] {
         &*self.ptr
     }
diff --git a/src/test/run-pass/fixup-deref-mut.rs b/src/test/run-pass/fixup-deref-mut.rs
index d2812ce1d2c..8fb3893e5de 100644
--- a/src/test/run-pass/fixup-deref-mut.rs
+++ b/src/test/run-pass/fixup-deref-mut.rs
@@ -8,18 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
+use std::ops::{Deref, DerefMut};
+
 // Generic unique/owned smaht pointer.
 struct Own<T> {
     value: *mut T
 }
 
-impl<T> Deref<T> for Own<T> {
+impl<T> Deref for Own<T> {
+    type Target = T;
+
     fn deref<'a>(&'a self) -> &'a T {
         unsafe { &*self.value }
     }
 }
 
-impl<T> DerefMut<T> for Own<T> {
+impl<T> DerefMut for Own<T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         unsafe { &mut *self.value }
     }
diff --git a/src/test/run-pass/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs
index 750c0c8ed68..8a75fdd685d 100644
--- a/src/test/run-pass/foreign-fn-linkname.rs
+++ b/src/test/run-pass/foreign-fn-linkname.rs
@@ -11,10 +11,10 @@
 // ignore-fast doesn't like extern crate
 
 extern crate libc;
+use std::c_str::ToCStr;
 
 mod mlibc {
-    extern crate libc;
-    use self::libc::{c_char, size_t};
+    use libc::{c_char, size_t};
 
     extern {
         #[link_name = "strlen"]
diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs
index a92b361dd33..162d7f10255 100644
--- a/src/test/run-pass/hashmap-memory.rs
+++ b/src/test/run-pass/hashmap-memory.rs
@@ -9,9 +9,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-extern crate collections;
-
 /**
    A somewhat reduced test case to expose some Valgrind issues.
 
@@ -24,6 +21,7 @@ pub fn map(filename: String, emit: map_reduce::putter) {
 
 mod map_reduce {
     use std::collections::HashMap;
+    use std::sync::mpsc::{channel, Sender};
     use std::str;
     use std::task;
 
@@ -52,16 +50,16 @@ mod map_reduce {
             }
             let (tx, rx) = channel();
             println!("sending find_reducer");
-            ctrl.send(ctrl_proto::find_reducer(key.as_bytes().to_vec(), tx));
+            ctrl.send(ctrl_proto::find_reducer(key.as_bytes().to_vec(), tx)).unwrap();
             println!("receiving");
-            let c = rx.recv();
+            let c = rx.recv().unwrap();
             println!("{}", c);
             im.insert(key, c);
         }
 
         let ctrl_clone = ctrl.clone();
         ::map(input, |a,b| emit(&mut intermediates, ctrl.clone(), a, b) );
-        ctrl_clone.send(ctrl_proto::mapper_done);
+        ctrl_clone.send(ctrl_proto::mapper_done).unwrap();
     }
 
     pub fn map_reduce(inputs: Vec<String>) {
@@ -79,7 +77,7 @@ mod map_reduce {
         let mut num_mappers = inputs.len() as int;
 
         while num_mappers > 0 {
-            match rx.recv() {
+            match rx.recv().unwrap() {
               ctrl_proto::mapper_done => { num_mappers -= 1; }
               ctrl_proto::find_reducer(k, cc) => {
                 let mut c;
@@ -88,7 +86,7 @@ mod map_reduce {
                   Some(&_c) => { c = _c; }
                   None => { c = 0; }
                 }
-                cc.send(c);
+                cc.send(c).unwrap();
               }
             }
         }
diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs
index fa62699a303..1efae89f665 100644
--- a/src/test/run-pass/ifmt.rs
+++ b/src/test/run-pass/ifmt.rs
@@ -16,7 +16,6 @@
 #![allow(unused_must_use)]
 
 use std::fmt;
-use std::io;
 
 struct A;
 struct B;
@@ -24,17 +23,17 @@ struct C;
 
 impl fmt::LowerHex for A {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write("aloha".as_bytes())
+        f.write_str("aloha")
     }
 }
 impl fmt::UpperHex for B {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write("adios".as_bytes())
+        f.write_str("adios")
     }
 }
 impl fmt::Show for C {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.pad_integral(true, "☃", "123".as_bytes())
+        f.pad_integral(true, "☃", "123")
     }
 }
 
@@ -160,18 +159,18 @@ pub fn main() {
 // Basic test to make sure that we can invoke the `write!` macro with an
 // io::Writer instance.
 fn test_write() {
-    let mut buf = Vec::new();
-    write!(&mut buf as &mut io::Writer, "{}", 3i);
+    use std::fmt::Writer;
+    let mut buf = String::new();
+    write!(&mut buf, "{}", 3i);
     {
-        let w = &mut buf as &mut io::Writer;
+        let w = &mut buf;
         write!(w, "{foo}", foo=4i);
         write!(w, "{}", "hello");
         writeln!(w, "{}", "line");
         writeln!(w, "{foo}", foo="bar");
     }
 
-    let s = String::from_utf8(buf).unwrap();
-    t!(s, "34helloline\nbar\n");
+    t!(buf, "34helloline\nbar\n");
 }
 
 // Just make sure that the macros are defined, there's not really a lot that we
@@ -187,14 +186,15 @@ fn test_print() {
 // Just make sure that the macros are defined, there's not really a lot that we
 // can do with them just yet (to test the output)
 fn test_format_args() {
-    let mut buf = Vec::new();
+    use std::fmt::Writer;
+    let mut buf = String::new();
     {
-        let w = &mut buf as &mut io::Writer;
+        let w = &mut buf;
         write!(w, "{}", format_args!("{}", 1i));
         write!(w, "{}", format_args!("test"));
         write!(w, "{}", format_args!("{test}", test=3i));
     }
-    let s = String::from_utf8(buf).unwrap();
+    let s = buf;
     t!(s, "1test3");
 
     let s = fmt::format(format_args!("hello {}", "world"));
diff --git a/src/test/run-pass/issue-11881.rs b/src/test/run-pass/issue-11881.rs
index 9008e8468f4..24deb7c2e4b 100644
--- a/src/test/run-pass/issue-11881.rs
+++ b/src/test/run-pass/issue-11881.rs
@@ -8,11 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(old_orphan_check)]
+
 extern crate rbml;
 extern crate serialize;
 
 use std::io;
-use std::io::{IoError, IoResult, SeekStyle};
+use std::fmt;
+use std::io::{IoResult, SeekStyle};
 use std::slice;
 
 use serialize::{Encodable, Encoder};
@@ -37,16 +40,15 @@ enum WireProtocol {
     // ...
 }
 
-fn encode_json<'a,
-               T: Encodable<json::Encoder<'a>,
-                            std::io::IoError>>(val: &T,
-                                               wr: &'a mut SeekableMemWriter) {
-    let mut encoder = json::Encoder::new(wr);
-    val.encode(&mut encoder);
+fn encode_json<
+               T: for<'a> Encodable<json::Encoder<'a>,
+                            fmt::Error>>(val: &T,
+                                               wr: &mut SeekableMemWriter) {
+    write!(wr, "{}", json::as_json(val));
 }
 fn encode_rbml<'a,
                T: Encodable<writer::Encoder<'a, SeekableMemWriter>,
-                            std::io::IoError>>(val: &T,
+                            io::IoError>>(val: &T,
                                                wr: &'a mut SeekableMemWriter) {
     let mut encoder = writer::Encoder::new(wr);
     val.encode(&mut encoder);
diff --git a/src/test/run-pass/issue-13264.rs b/src/test/run-pass/issue-13264.rs
index c416d30f776..00b508ab92c 100644
--- a/src/test/run-pass/issue-13264.rs
+++ b/src/test/run-pass/issue-13264.rs
@@ -8,11 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
+use std::ops::Deref;
+
 struct Root {
     jsref: JSRef
 }
 
-impl Deref<JSRef> for Root {
+impl Deref for Root {
+    type Target = JSRef;
+
     fn deref<'a>(&'a self) -> &'a JSRef {
         &self.jsref
     }
@@ -23,7 +29,9 @@ struct JSRef {
     node: *const Node
 }
 
-impl Deref<Node> for JSRef {
+impl Deref for JSRef {
+    type Target = Node;
+
     fn deref<'a>(&'a self) -> &'a Node {
         self.get()
     }
diff --git a/src/test/run-pass/issue-13494.rs b/src/test/run-pass/issue-13494.rs
index be851ddefc6..b9339c1cc0d 100644
--- a/src/test/run-pass/issue-13494.rs
+++ b/src/test/run-pass/issue-13494.rs
@@ -11,22 +11,25 @@
 // This test may not always fail, but it can be flaky if the race it used to
 // expose is still present.
 
+use std::sync::mpsc::{channel, Sender, Receiver};
+use std::thread::Thread;
+
 fn helper(rx: Receiver<Sender<()>>) {
     for tx in rx.iter() {
-        let _ = tx.send_opt(());
+        let _ = tx.send(());
     }
 }
 
 fn main() {
     let (tx, rx) = channel();
-    spawn(move|| { helper(rx) });
+    let _t = Thread::spawn(move|| { helper(rx) }).detach();
     let (snd, rcv) = channel::<int>();
     for _ in range(1i, 100000i) {
-        snd.send(1i);
+        snd.send(1i).unwrap();
         let (tx2, rx2) = channel();
-        tx.send(tx2);
+        tx.send(tx2).unwrap();
         select! {
-            () = rx2.recv() => (),
+            _ = rx2.recv() => (),
             _ = rcv.recv() => ()
         }
     }
diff --git a/src/test/run-pass/issue-14021.rs b/src/test/run-pass/issue-14021.rs
index 612ed6b70b4..509459a2ab3 100644
--- a/src/test/run-pass/issue-14021.rs
+++ b/src/test/run-pass/issue-14021.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(old_orphan_check)]
 
 extern crate serialize;
 
diff --git a/src/test/run-pass/issue-15734.rs b/src/test/run-pass/issue-15734.rs
index ea5bd550d53..e99b1dc5bef 100644
--- a/src/test/run-pass/issue-15734.rs
+++ b/src/test/run-pass/issue-15734.rs
@@ -8,6 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// If `Index` used an associated type for its output, this test would
+// work more smoothly.
+#![feature(old_orphan_check)]
+
+use std::ops::Index;
+
 struct Mat<T> { data: Vec<T>, cols: uint, }
 
 impl<T> Mat<T> {
diff --git a/src/test/run-pass/issue-15924.rs b/src/test/run-pass/issue-15924.rs
index 8d5b928964d..1ab8deda383 100644
--- a/src/test/run-pass/issue-15924.rs
+++ b/src/test/run-pass/issue-15924.rs
@@ -12,7 +12,7 @@
 
 extern crate serialize;
 
-use std::io::IoError;
+use std::fmt;
 use serialize::{Encoder, Encodable};
 use serialize::json;
 
@@ -21,7 +21,7 @@ struct Foo<T> {
 }
 
 #[unsafe_destructor]
-impl<'a, T: Encodable<json::Encoder<'a>, IoError>> Drop for Foo<T> {
+impl<T: for<'a> Encodable<json::Encoder<'a>, fmt::Error>> Drop for Foo<T> {
     fn drop(&mut self) {
         json::encode(&self.v);
     }
diff --git a/src/test/run-pass/issue-16560.rs b/src/test/run-pass/issue-16560.rs
index f329e7eed0d..b2b819a1103 100644
--- a/src/test/run-pass/issue-16560.rs
+++ b/src/test/run-pass/issue-16560.rs
@@ -10,6 +10,7 @@
 
 #![feature(unboxed_closures)]
 
+use std::thread::Thread;
 use std::mem;
 
 fn main() {
@@ -19,7 +20,7 @@ fn main() {
     // Check that both closures are capturing by value
     assert_eq!(1, mem::size_of_val(&closure));
 
-    spawn(move|| {
+    Thread::spawn(move|| {
         let ok = closure;
-    })
+    }).join().ok().unwrap();
 }
diff --git a/src/test/run-pass/issue-16774.rs b/src/test/run-pass/issue-16774.rs
index ebc879d82fb..45cfabcd872 100644
--- a/src/test/run-pass/issue-16774.rs
+++ b/src/test/run-pass/issue-16774.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+#![feature(associated_types, unboxed_closures)]
+
+use std::ops::{Deref, DerefMut};
 
 struct X(Box<int>);
 
@@ -23,14 +25,16 @@ impl Drop for X {
     }
 }
 
-impl Deref<int> for X {
+impl Deref for X {
+    type Target = int;
+
     fn deref(&self) -> &int {
         let &X(box ref x) = self;
         x
     }
 }
 
-impl DerefMut<int> for X {
+impl DerefMut for X {
     fn deref_mut(&mut self) -> &mut int {
         let &X(box ref mut x) = self;
         x
diff --git a/src/test/run-pass/issue-17718.rs b/src/test/run-pass/issue-17718.rs
index 90a102222ba..10ad0f620e9 100644
--- a/src/test/run-pass/issue-17718.rs
+++ b/src/test/run-pass/issue-17718.rs
@@ -15,7 +15,7 @@ extern crate "issue-17718" as other;
 use std::sync::atomic;
 
 const C1: uint = 1;
-const C2: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+const C2: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
 const C3: fn() = foo;
 const C4: uint = C1 * C1 + C1 / C1;
 const C5: &'static uint = &C4;
@@ -25,7 +25,7 @@ const C6: uint = {
 };
 
 static S1: uint = 3;
-static S2: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
+static S2: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
 
 mod test {
     static A: uint = 4;
diff --git a/src/test/run-pass/issue-17732.rs b/src/test/run-pass/issue-17732.rs
new file mode 100644
index 00000000000..45d3b53132d
--- /dev/null
+++ b/src/test/run-pass/issue-17732.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_types)]
+trait Person {
+    type string;
+}
+
+struct Someone<P: Person>;
+
+fn main() {}
diff --git a/src/test/run-pass/issue-19479.rs b/src/test/run-pass/issue-19479.rs
new file mode 100644
index 00000000000..b3354530a0c
--- /dev/null
+++ b/src/test/run-pass/issue-19479.rs
@@ -0,0 +1,23 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_types)]
+trait Base {}
+trait AssocA {
+    type X: Base;
+}
+trait AssocB {
+    type Y: Base;
+}
+impl<T: AssocA> AssocB for T {
+    type Y = <T as AssocA>::X;
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-19631.rs b/src/test/run-pass/issue-19631.rs
new file mode 100644
index 00000000000..d036bab99f8
--- /dev/null
+++ b/src/test/run-pass/issue-19631.rs
@@ -0,0 +1,23 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_types)]
+
+trait PoolManager {
+    type C;
+}
+
+struct InnerPool<M> {
+    manager: M,
+}
+
+impl<M> InnerPool<M> where M: PoolManager {}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-19632.rs b/src/test/run-pass/issue-19632.rs
new file mode 100644
index 00000000000..9bc74e50173
--- /dev/null
+++ b/src/test/run-pass/issue-19632.rs
@@ -0,0 +1,21 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_types)]
+
+trait PoolManager {
+    type C;
+}
+
+struct InnerPool<M: PoolManager> {
+    manager: M,
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-19850.rs b/src/test/run-pass/issue-19850.rs
new file mode 100644
index 00000000000..cd56fe18689
--- /dev/null
+++ b/src/test/run-pass/issue-19850.rs
@@ -0,0 +1,30 @@
+// Copyright 2015 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.
+
+// Test that `<Type as Trait>::Output` and `Self::Output` are accepted as type annotations in let
+// bindings
+
+#![feature(associated_types)]
+
+trait Int {
+    fn one() -> Self;
+    fn leading_zeros(self) -> uint;
+}
+
+trait Foo {
+    type T : Int;
+
+    fn test(&self) {
+        let r: <Self as Foo>::T = Int::one();
+        let r: Self::T = Int::one();
+    }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-20009.rs b/src/test/run-pass/issue-20009.rs
new file mode 100644
index 00000000000..535538793d1
--- /dev/null
+++ b/src/test/run-pass/issue-20009.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+// Check that associated types are `Sized`
+
+#![feature(associated_types)]
+
+trait Trait {
+    type Output;
+
+    fn is_sized(&self) -> Self::Output;
+    fn wasnt_sized(&self) -> Self::Output { loop {} }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-20313.rs b/src/test/run-pass/issue-20313.rs
new file mode 100644
index 00000000000..47791ceecb6
--- /dev/null
+++ b/src/test/run-pass/issue-20313.rs
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![feature(link_llvm_intrinsics)]
+
+extern {
+    #[link_name = "llvm.sqrt.f32"]
+    fn sqrt(x: f32) -> f32;
+}
+
+fn main(){
+}
diff --git a/src/test/run-pass/issue-20389.rs b/src/test/run-pass/issue-20389.rs
new file mode 100644
index 00000000000..0ef14149c94
--- /dev/null
+++ b/src/test/run-pass/issue-20389.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+// aux-build:issue_20389.rs
+
+#![feature(associated_types)]
+extern crate issue_20389;
+
+struct Foo;
+
+impl issue_20389::T for Foo {
+    type C = ();
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs
index f17f9411d15..a02dbb6035b 100644
--- a/src/test/run-pass/issue-3609.rs
+++ b/src/test/run-pass/issue-3609.rs
@@ -11,6 +11,7 @@
 #![feature(default_type_params)]
 
 use std::task;
+use std::sync::mpsc::Sender;
 use std::thunk::Invoke;
 
 type RingBuffer = Vec<f64> ;
diff --git a/src/test/run-pass/issue-3743.rs b/src/test/run-pass/issue-3743.rs
index 80d3d29bc00..cb4f1b7d20f 100644
--- a/src/test/run-pass/issue-3743.rs
+++ b/src/test/run-pass/issue-3743.rs
@@ -8,6 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// If `Mul` used an associated type for its output, this test would
+// work more smoothly.
+#![feature(old_orphan_check)]
+
+use std::ops::Mul;
+
 struct Vec2 {
     x: f64,
     y: f64
diff --git a/src/test/run-pass/issue-3979-generics.rs b/src/test/run-pass/issue-3979-generics.rs
index 86cdd6135ec..93c72e2e350 100644
--- a/src/test/run-pass/issue-3979-generics.rs
+++ b/src/test/run-pass/issue-3979-generics.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ops::Add;
+
 trait Positioned<S> {
   fn SetX(&mut self, S);
   fn X(&self) -> S;
diff --git a/src/test/run-pass/issue-4446.rs b/src/test/run-pass/issue-4446.rs
index daa80aec28c..30e1a14ecff 100644
--- a/src/test/run-pass/issue-4446.rs
+++ b/src/test/run-pass/issue-4446.rs
@@ -9,13 +9,15 @@
 // except according to those terms.
 
 use std::io::println;
+use std::sync::mpsc::channel;
+use std::thread::Thread;
 
 pub fn main() {
     let (tx, rx) = channel();
 
-    tx.send("hello, world");
+    tx.send("hello, world").unwrap();
 
-    spawn(move|| {
-        println(rx.recv());
-    });
+    Thread::spawn(move|| {
+        println(rx.recv().unwrap());
+    }).join().ok().unwrap();
 }
diff --git a/src/test/run-pass/issue-4448.rs b/src/test/run-pass/issue-4448.rs
index 3ea968c416f..7e53722726f 100644
--- a/src/test/run-pass/issue-4448.rs
+++ b/src/test/run-pass/issue-4448.rs
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::task;
+use std::sync::mpsc::channel;
+use std::thread::Thread;
 
 pub fn main() {
     let (tx, rx) = channel::<&'static str>();
 
-    task::spawn(move|| {
-        assert_eq!(rx.recv(), "hello, world");
+    let t = Thread::spawn(move|| {
+        assert_eq!(rx.recv().unwrap(), "hello, world");
     });
 
-    tx.send("hello, world");
+    tx.send("hello, world").unwrap();
+    t.join().ok().unwrap();
 }
diff --git a/src/test/run-pass/issue-7784.rs b/src/test/run-pass/issue-7784.rs
index b936eb322fc..43785edc2eb 100644
--- a/src/test/run-pass/issue-7784.rs
+++ b/src/test/run-pass/issue-7784.rs
@@ -10,6 +10,8 @@
 
 #![feature(advanced_slice_patterns)]
 
+use std::ops::Add;
+
 fn foo<T: Add<T, T> + Clone>([x, y, z]: [T; 3]) -> (T, T, T) {
     (x.clone(), x.clone() + y.clone(), x + y + z)
 }
diff --git a/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs b/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs
index aaf2ecb7129..3238c24163e 100644
--- a/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs
+++ b/src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs
@@ -16,7 +16,7 @@
 
 fn require_send<T: Send>(_: T){}
 
-trait TragicallySelfIsNotSend: Send {
+trait TragicallySelfIsNotSend: Send + Sized {
     fn x(self) {
         require_send(self);
     }
diff --git a/src/test/run-pass/issue-8827.rs b/src/test/run-pass/issue-8827.rs
index 7397ad74495..39695a8339f 100644
--- a/src/test/run-pass/issue-8827.rs
+++ b/src/test/run-pass/issue-8827.rs
@@ -8,37 +8,40 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::thread::Thread;
+use std::sync::mpsc::{channel, Receiver};
+
 fn periodical(n: int) -> Receiver<bool> {
     let (chan, port) = channel();
-    spawn(move|| {
+    Thread::spawn(move|| {
         loop {
             for _ in range(1, n) {
-                match chan.send_opt(false) {
+                match chan.send(false) {
                     Ok(()) => {}
                     Err(..) => break,
                 }
             }
-            match chan.send_opt(true) {
+            match chan.send(true) {
                 Ok(()) => {}
                 Err(..) => break
             }
         }
-    });
+    }).detach();
     return port;
 }
 
 fn integers() -> Receiver<int> {
     let (chan, port) = channel();
-    spawn(move|| {
+    Thread::spawn(move|| {
         let mut i = 1;
         loop {
-            match chan.send_opt(i) {
+            match chan.send(i) {
                 Ok(()) => {}
                 Err(..) => break,
             }
             i = i + 1;
         }
-    });
+    }).detach();
     return port;
 }
 
@@ -47,7 +50,7 @@ fn main() {
     let threes = periodical(3);
     let fives = periodical(5);
     for _ in range(1i, 100i) {
-        match (ints.recv(), threes.recv(), fives.recv()) {
+        match (ints.recv().unwrap(), threes.recv().unwrap(), fives.recv().unwrap()) {
             (_, true, true) => println!("FizzBuzz"),
             (_, true, false) => println!("Fizz"),
             (_, false, true) => println!("Buzz"),
diff --git a/src/test/run-pass/issue-9396.rs b/src/test/run-pass/issue-9396.rs
index 588e0c1cf16..34bb50c5cf6 100644
--- a/src/test/run-pass/issue-9396.rs
+++ b/src/test/run-pass/issue-9396.rs
@@ -8,22 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::comm;
+use std::sync::mpsc::{TryRecvError, channel};
 use std::io::timer::Timer;
+use std::thread::Thread;
 use std::time::Duration;
 
 pub fn main() {
     let (tx, rx) = channel();
-    spawn(move||{
+    let _t = Thread::spawn(move||{
         let mut timer = Timer::new().unwrap();
         timer.sleep(Duration::milliseconds(10));
-        tx.send(());
+        tx.send(()).unwrap();
     });
     loop {
         match rx.try_recv() {
             Ok(()) => break,
-            Err(comm::Empty) => {}
-            Err(comm::Disconnected) => unreachable!()
+            Err(TryRecvError::Empty) => {}
+            Err(TryRecvError::Disconnected) => unreachable!()
         }
     }
 }
diff --git a/src/test/run-pass/ivec-tag.rs b/src/test/run-pass/ivec-tag.rs
index 1f7edcf43b8..a9a50b9ef25 100644
--- a/src/test/run-pass/ivec-tag.rs
+++ b/src/test/run-pass/ivec-tag.rs
@@ -9,11 +9,12 @@
 // except according to those terms.
 
 use std::task;
+use std::sync::mpsc::{channel, Sender};
 
 fn producer(tx: &Sender<Vec<u8>>) {
     tx.send(
          vec!(1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8,
-          13u8));
+          13u8)).unwrap();
 }
 
 pub fn main() {
@@ -22,5 +23,5 @@ pub fn main() {
         producer(&tx)
     });
 
-    let _data: Vec<u8> = rx.recv();
+    let _data: Vec<u8> = rx.recv().unwrap();
 }
diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs
index 1e05c05cc0d..509afff3d13 100644
--- a/src/test/run-pass/logging-only-prints-once.rs
+++ b/src/test/run-pass/logging-only-prints-once.rs
@@ -13,6 +13,7 @@
 
 use std::cell::Cell;
 use std::fmt;
+use std::thread::Thread;
 
 struct Foo(Cell<int>);
 
@@ -26,13 +27,10 @@ impl fmt::Show for Foo {
 }
 
 pub fn main() {
-    let (tx, rx) = channel();
-    spawn(move|| {
+    Thread::spawn(move|| {
         let mut f = Foo(Cell::new(0));
         println!("{}", f);
         let Foo(ref mut f) = f;
         assert!(f.get() == 1);
-        tx.send(());
-    });
-    rx.recv();
+    }).join().ok().unwrap();
 }
diff --git a/src/test/run-pass/macro-with-braces-in-expr-position.rs b/src/test/run-pass/macro-with-braces-in-expr-position.rs
index 024dc4c03e1..a6e579ddff3 100644
--- a/src/test/run-pass/macro-with-braces-in-expr-position.rs
+++ b/src/test/run-pass/macro-with-braces-in-expr-position.rs
@@ -10,11 +10,13 @@
 
 #![feature(macro_rules)]
 
+use std::thread::Thread;
+
 macro_rules! expr (($e: expr) => { $e });
 
 macro_rules! spawn {
     ($($code: tt)*) => {
-        expr!(spawn(move|| {$($code)*}))
+        expr!(Thread::spawn(move|| {$($code)*}).detach())
     }
 }
 
diff --git a/src/test/run-pass/match-with-ret-arm.rs b/src/test/run-pass/match-with-ret-arm.rs
index 2109f7ef1ea..2cba1dec2dc 100644
--- a/src/test/run-pass/match-with-ret-arm.rs
+++ b/src/test/run-pass/match-with-ret-arm.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::uint;
+use std::str::from_str;
 
 pub fn main() {
     // sometimes we have had trouble finding
diff --git a/src/test/run-pass/method-self-arg-trait.rs b/src/test/run-pass/method-self-arg-trait.rs
index 36dfe83a9eb..29d100beb06 100644
--- a/src/test/run-pass/method-self-arg-trait.rs
+++ b/src/test/run-pass/method-self-arg-trait.rs
@@ -16,7 +16,7 @@ struct Foo;
 
 impl Copy for Foo {}
 
-trait Bar {
+trait Bar : Sized {
     fn foo1(&self);
     fn foo2(self);
     fn foo3(self: Box<Self>);
diff --git a/src/test/run-pass/numeric-method-autoexport.rs b/src/test/run-pass/numeric-method-autoexport.rs
index f8184d248ff..b4d079d79d6 100644
--- a/src/test/run-pass/numeric-method-autoexport.rs
+++ b/src/test/run-pass/numeric-method-autoexport.rs
@@ -15,6 +15,9 @@
 // necessary. Testing the methods of the impls is done within the source
 // file for each numeric type.
 
+use std::ops::Add;
+use std::num::ToPrimitive;
+
 pub fn main() {
 // ints
     // num
diff --git a/src/test/run-pass/out-of-stack-new-thread-no-split.rs b/src/test/run-pass/out-of-stack-new-thread-no-split.rs
index 674d0dc86da..7aac2d705a8 100644
--- a/src/test/run-pass/out-of-stack-new-thread-no-split.rs
+++ b/src/test/run-pass/out-of-stack-new-thread-no-split.rs
@@ -17,6 +17,7 @@
 
 use std::io::process::Command;
 use std::os;
+use std::thread::Thread;
 
 // lifted from the test module
 // Inlining to avoid llvm turning the recursive functions into tail calls,
@@ -36,12 +37,7 @@ fn main() {
     let args = os::args();
     let args = args.as_slice();
     if args.len() > 1 && args[1].as_slice() == "recurse" {
-        let (tx, rx) = channel();
-        spawn(move|| {
-            recurse();
-            tx.send(());
-        });
-        rx.recv();
+        let _t = Thread::spawn(recurse);
     } else {
         let recurse = Command::new(args[0].as_slice()).arg("recurse").output().unwrap();
         assert!(!recurse.status.success());
diff --git a/src/test/run-pass/overloaded-autoderef-count.rs b/src/test/run-pass/overloaded-autoderef-count.rs
index baf1b1b0237..e9eb924d449 100644
--- a/src/test/run-pass/overloaded-autoderef-count.rs
+++ b/src/test/run-pass/overloaded-autoderef-count.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::cell::Cell;
 use std::ops::{Deref, DerefMut};
 
@@ -32,14 +34,16 @@ impl<T> DerefCounter<T> {
     }
 }
 
-impl<T> Deref<T> for DerefCounter<T> {
+impl<T> Deref for DerefCounter<T> {
+    type Target = T;
+
     fn deref(&self) -> &T {
         self.count_imm.set(self.count_imm.get() + 1);
         &self.value
     }
 }
 
-impl<T> DerefMut<T> for DerefCounter<T> {
+impl<T> DerefMut for DerefCounter<T> {
     fn deref_mut(&mut self) -> &mut T {
         self.count_mut += 1;
         &mut self.value
diff --git a/src/test/run-pass/overloaded-autoderef-indexing.rs b/src/test/run-pass/overloaded-autoderef-indexing.rs
index 5c4befcd0c8..6d8d09b321e 100644
--- a/src/test/run-pass/overloaded-autoderef-indexing.rs
+++ b/src/test/run-pass/overloaded-autoderef-indexing.rs
@@ -8,11 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
+use std::ops::Deref;
+
 struct DerefArray<'a, T:'a> {
     inner: &'a [T]
 }
 
-impl<'a, T> Deref<&'a [T]> for DerefArray<'a, T> {
+impl<'a, T> Deref for DerefArray<'a, T> {
+    type Target = &'a [T];
+
     fn deref<'b>(&'b self) -> &'b &'a [T] {
         &self.inner
     }
diff --git a/src/test/run-pass/overloaded-autoderef-order.rs b/src/test/run-pass/overloaded-autoderef-order.rs
index f0daf371ca7..cafb665fc37 100644
--- a/src/test/run-pass/overloaded-autoderef-order.rs
+++ b/src/test/run-pass/overloaded-autoderef-order.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::rc::Rc;
+use std::ops::Deref;
 
 struct DerefWrapper<X, Y> {
     x: X,
@@ -23,13 +26,17 @@ impl<X, Y> DerefWrapper<X, Y> {
     }
 }
 
-impl<X, Y> Deref<Y> for DerefWrapper<X, Y> {
+impl<X, Y> Deref for DerefWrapper<X, Y> {
+    type Target = Y;
+
     fn deref(&self) -> &Y {
         &self.y
     }
 }
 
 mod priv_test {
+    use std::ops::Deref;
+
     pub struct DerefWrapperHideX<X, Y> {
         x: X,
         pub y: Y
@@ -46,7 +53,9 @@ mod priv_test {
         }
     }
 
-    impl<X, Y> Deref<Y> for DerefWrapperHideX<X, Y> {
+    impl<X, Y> Deref for DerefWrapperHideX<X, Y> {
+        type Target = Y;
+
         fn deref(&self) -> &Y {
             &self.y
         }
diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs
index f71afb96507..23efba15749 100644
--- a/src/test/run-pass/overloaded-autoderef-vtable.rs
+++ b/src/test/run-pass/overloaded-autoderef-vtable.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
@@ -24,7 +26,9 @@ impl<T> Helper<T> for Option<T> {
     }
 }
 
-impl<T, H: Helper<T>> Deref<T> for DerefWithHelper<H, T> {
+impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
+    type Target = T;
+
     fn deref(&self) -> &T {
         self.helper.helper_borrow()
     }
diff --git a/src/test/run-pass/overloaded-autoderef.rs b/src/test/run-pass/overloaded-autoderef.rs
index 344b27ef35f..949a7b158d4 100644
--- a/src/test/run-pass/overloaded-autoderef.rs
+++ b/src/test/run-pass/overloaded-autoderef.rs
@@ -10,7 +10,7 @@
 
 use std::cell::RefCell;
 use std::rc::Rc;
-use std::string::String;
+use std::num::ToPrimitive;
 
 #[derive(PartialEq, Show)]
 struct Point {
@@ -31,7 +31,6 @@ pub fn main() {
     assert_eq!((i_value, *i.borrow()), (2, 5));
 
     let s = Rc::new("foo".to_string());
-    assert!(s.equiv(&("foo")));
     assert_eq!(s.as_slice(), "foo");
 
     let mut_s = Rc::new(RefCell::new(String::from_str("foo")));
diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs
index 2e8ec3916bd..bdaccee65d7 100644
--- a/src/test/run-pass/overloaded-calls-param-vtables.rs
+++ b/src/test/run-pass/overloaded-calls-param-vtables.rs
@@ -13,10 +13,11 @@
 #![feature(unboxed_closures)]
 
 use std::ops::Fn;
+use std::ops::Add;
 
-struct G;
+struct G<A>;
 
-impl<'a, A: Add<int, int>> Fn<(A,), int> for G {
+impl<'a, A: Add<int, int>> Fn<(A,), int> for G<A> {
     extern "rust-call" fn call(&self, (arg,): (A,)) -> int {
         arg.add(1)
     }
diff --git a/src/test/run-pass/overloaded-deref-count.rs b/src/test/run-pass/overloaded-deref-count.rs
index 7645500c02f..b6fb38d5cc2 100644
--- a/src/test/run-pass/overloaded-deref-count.rs
+++ b/src/test/run-pass/overloaded-deref-count.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::cell::Cell;
 use std::ops::{Deref, DerefMut};
 use std::vec::Vec;
@@ -32,14 +34,16 @@ impl<T> DerefCounter<T> {
     }
 }
 
-impl<T> Deref<T> for DerefCounter<T> {
+impl<T> Deref for DerefCounter<T> {
+    type Target = T;
+
     fn deref(&self) -> &T {
         self.count_imm.set(self.count_imm.get() + 1);
         &self.value
     }
 }
 
-impl<T> DerefMut<T> for DerefCounter<T> {
+impl<T> DerefMut for DerefCounter<T> {
     fn deref_mut(&mut self) -> &mut T {
         self.count_mut += 1;
         &mut self.value
diff --git a/src/test/run-pass/overloaded-index-autoderef.rs b/src/test/run-pass/overloaded-index-autoderef.rs
index d51956da894..dcb0c40c608 100644
--- a/src/test/run-pass/overloaded-index-autoderef.rs
+++ b/src/test/run-pass/overloaded-index-autoderef.rs
@@ -10,6 +10,8 @@
 
 // Test overloaded indexing combined with autoderef.
 
+use std::ops::{Index, IndexMut};
+
 struct Foo {
     x: int,
     y: int,
diff --git a/src/test/run-pass/overloaded-index-in-field.rs b/src/test/run-pass/overloaded-index-in-field.rs
index e8b0408ca0d..1c06ed64fc7 100644
--- a/src/test/run-pass/overloaded-index-in-field.rs
+++ b/src/test/run-pass/overloaded-index-in-field.rs
@@ -11,6 +11,8 @@
 // Test using overloaded indexing when the "map" is stored in a
 // field. This caused problems at some point.
 
+use std::ops::Index;
+
 struct Foo {
     x: int,
     y: int,
diff --git a/src/test/run-pass/overloaded-index.rs b/src/test/run-pass/overloaded-index.rs
index 23bebfa35d7..fdf7e7e2cbb 100644
--- a/src/test/run-pass/overloaded-index.rs
+++ b/src/test/run-pass/overloaded-index.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ops::{Index, IndexMut};
+
 struct Foo {
     x: int,
     y: int,
diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs
index b5cee20232b..c7aa405b513 100644
--- a/src/test/run-pass/rename-directory.rs
+++ b/src/test/run-pass/rename-directory.rs
@@ -14,6 +14,7 @@
 extern crate libc;
 
 use std::io::TempDir;
+use std::c_str::ToCStr;
 use std::io::fs::PathExtensions;
 use std::io::fs;
 use std::io;
diff --git a/src/test/run-pass/running-with-no-runtime.rs b/src/test/run-pass/running-with-no-runtime.rs
index 4cf8c52f2bb..0aeade935da 100644
--- a/src/test/run-pass/running-with-no-runtime.rs
+++ b/src/test/run-pass/running-with-no-runtime.rs
@@ -10,12 +10,12 @@
 
 use std::io::process::{Command, ProcessOutput};
 use std::os;
-use std::str;
+use std::rt::unwind::try;
 use std::rt;
+use std::str;
+use std::thread::Thread;
 use std::thunk::Thunk;
 
-use std::rt::unwind::try;
-
 #[start]
 fn start(argc: int, argv: *const *const u8) -> int {
     if argc > 1 {
@@ -25,8 +25,7 @@ fn start(argc: int, argv: *const *const u8) -> int {
                 2 => println!("foo"),
                 3 => assert!(try(|| {}).is_ok()),
                 4 => assert!(try(|| panic!()).is_err()),
-                5 => assert!(try(|| spawn(move|| {})).is_err()),
-                6 => assert!(Command::new("test").spawn().is_err()),
+                5 => assert!(Command::new("test").spawn().is_err()),
                 _ => panic!()
             }
         }
@@ -50,8 +49,6 @@ fn start(argc: int, argv: *const *const u8) -> int {
     pass(Command::new(me).arg(x).output().unwrap());
     let x: &[u8] = &[5u8];
     pass(Command::new(me).arg(x).output().unwrap());
-    let x: &[u8] = &[6u8];
-    pass(Command::new(me).arg(x).output().unwrap());
 
     0
 }
diff --git a/src/test/run-pass/rust-log-filter.rs b/src/test/run-pass/rust-log-filter.rs
index 88d30318f2a..2612483ded4 100644
--- a/src/test/run-pass/rust-log-filter.rs
+++ b/src/test/run-pass/rust-log-filter.rs
@@ -14,6 +14,9 @@
 #[phase(plugin,link)]
 extern crate log;
 
+use std::sync::mpsc::{channel, Sender, Receiver};
+use std::thread::Thread;
+
 pub struct ChannelLogger {
     tx: Sender<String>
 }
@@ -27,14 +30,14 @@ impl ChannelLogger {
 
 impl log::Logger for ChannelLogger {
     fn log(&mut self, record: &log::LogRecord) {
-        self.tx.send(format!("{}", record.args));
+        self.tx.send(format!("{}", record.args)).unwrap();
     }
 }
 
 pub fn main() {
     let (logger, rx) = ChannelLogger::new();
 
-    spawn(move|| {
+    let _t = Thread::spawn(move|| {
         log::set_logger(logger);
 
         // our regex is "f.o"
@@ -46,9 +49,9 @@ pub fn main() {
         info!("f1o");
     });
 
-    assert_eq!(rx.recv().as_slice(), "foo");
-    assert_eq!(rx.recv().as_slice(), "foo bar");
-    assert_eq!(rx.recv().as_slice(), "bar foo");
-    assert_eq!(rx.recv().as_slice(), "f1o");
-    assert!(rx.recv_opt().is_err());
+    assert_eq!(rx.recv().unwrap().as_slice(), "foo");
+    assert_eq!(rx.recv().unwrap().as_slice(), "foo bar");
+    assert_eq!(rx.recv().unwrap().as_slice(), "bar foo");
+    assert_eq!(rx.recv().unwrap().as_slice(), "f1o");
+    assert!(rx.recv().is_err());
 }
diff --git a/src/test/run-pass/self-in-mut-slot-default-method.rs b/src/test/run-pass/self-in-mut-slot-default-method.rs
index b4a46f34015..bced8012b68 100644
--- a/src/test/run-pass/self-in-mut-slot-default-method.rs
+++ b/src/test/run-pass/self-in-mut-slot-default-method.rs
@@ -13,7 +13,7 @@ struct X {
     a: int
 }
 
-trait Changer {
+trait Changer : Sized {
     fn change(mut self) -> Self {
         self.set_to(55);
         self
diff --git a/src/test/run-pass/send-resource.rs b/src/test/run-pass/send-resource.rs
index 6001c360ab9..7fd9706bd0f 100644
--- a/src/test/run-pass/send-resource.rs
+++ b/src/test/run-pass/send-resource.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::task;
+use std::sync::mpsc::channel;
 
 struct test {
   f: int,
@@ -29,10 +30,10 @@ pub fn main() {
 
     task::spawn(move|| {
         let (tx2, rx2) = channel();
-        tx.send(tx2);
+        tx.send(tx2).unwrap();
 
-        let _r = rx2.recv();
+        let _r = rx2.recv().unwrap();
     });
 
-    rx.recv().send(test(42));
+    rx.recv().unwrap().send(test(42)).unwrap();
 }
diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs
index 508bd99d77d..ae992a0a358 100644
--- a/src/test/run-pass/send-type-inference.rs
+++ b/src/test/run-pass/send-type-inference.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::{channel, Sender};
+
 // tests that ctrl's type gets inferred properly
 struct Command<K, V> {
     key: K,
diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs
index 1b0f2ec0a32..bfeff58b802 100644
--- a/src/test/run-pass/send_str_hashmap.rs
+++ b/src/test/run-pass/send_str_hashmap.rs
@@ -11,8 +11,8 @@
 extern crate collections;
 
 use std::collections::HashMap;
-use std::option::Option::Some;
 use std::str::SendStr;
+use std::borrow::IntoCow;
 
 pub fn main() {
     let mut map: HashMap<SendStr, uint> = HashMap::new();
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index 24480d85272..8c70738de48 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -11,9 +11,8 @@
 extern crate collections;
 
 use self::collections::BTreeMap;
-use std::option::Option::Some;
 use std::str::SendStr;
-use std::string::ToString;
+use std::borrow::IntoCow;
 
 pub fn main() {
     let mut map: BTreeMap<SendStr, uint> = BTreeMap::new();
diff --git a/src/test/run-pass/sendable-class.rs b/src/test/run-pass/sendable-class.rs
index 007a83d2c88..8691d5e875b 100644
--- a/src/test/run-pass/sendable-class.rs
+++ b/src/test/run-pass/sendable-class.rs
@@ -10,6 +10,8 @@
 
 // Test that a class with only sendable fields can be sent
 
+use std::sync::mpsc::channel;
+
 struct foo {
   i: int,
   j: char,
diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs
index 9b533c69f32..1c86e3e6ea2 100644
--- a/src/test/run-pass/spawn-types.rs
+++ b/src/test/run-pass/spawn-types.rs
@@ -15,6 +15,7 @@
  */
 
 use std::task;
+use std::sync::mpsc::{channel, Sender};
 
 type ctx = Sender<int>;
 
diff --git a/src/test/run-pass/supertrait-default-generics.rs b/src/test/run-pass/supertrait-default-generics.rs
index 873941395fe..4465561f874 100644
--- a/src/test/run-pass/supertrait-default-generics.rs
+++ b/src/test/run-pass/supertrait-default-generics.rs
@@ -10,6 +10,8 @@
 
 // There is some other borrowck bug, so we make the stuff not mut.
 
+use std::ops::Add;
+
 trait Positioned<S> {
   fn SetX(&mut self, S);
   fn X(&self) -> S;
diff --git a/src/test/run-pass/task-comm-0.rs b/src/test/run-pass/task-comm-0.rs
index 9e3511ba603..de077ffd190 100644
--- a/src/test/run-pass/task-comm-0.rs
+++ b/src/test/run-pass/task-comm-0.rs
@@ -8,28 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use std::task;
+use std::sync::mpsc::{channel, Sender};
 
 pub fn main() { test05(); }
 
 fn test05_start(tx : &Sender<int>) {
-    tx.send(10);
+    tx.send(10).unwrap();
     println!("sent 10");
-    tx.send(20);
+    tx.send(20).unwrap();
     println!("sent 20");
-    tx.send(30);
+    tx.send(30).unwrap();
     println!("sent 30");
 }
 
 fn test05() {
     let (tx, rx) = channel();
     task::spawn(move|| { test05_start(&tx) });
-    let mut value: int = rx.recv();
+    let mut value: int = rx.recv().unwrap();
     println!("{}", value);
-    value = rx.recv();
+    value = rx.recv().unwrap();
     println!("{}", value);
-    value = rx.recv();
+    value = rx.recv().unwrap();
     println!("{}", value);
     assert_eq!(value, 30);
 }
diff --git a/src/test/run-pass/task-comm-10.rs b/src/test/run-pass/task-comm-10.rs
index dd3c90991f6..93dca923b6b 100644
--- a/src/test/run-pass/task-comm-10.rs
+++ b/src/test/run-pass/task-comm-10.rs
@@ -8,19 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use std::task;
+use std::sync::mpsc::{channel, Sender};
 
 fn start(tx: &Sender<Sender<String>>) {
     let (tx2, rx) = channel();
-    tx.send(tx2);
+    tx.send(tx2).unwrap();
 
     let mut a;
     let mut b;
-    a = rx.recv();
+    a = rx.recv().unwrap();
     assert!(a == "A".to_string());
     println!("{}", a);
-    b = rx.recv();
+    b = rx.recv().unwrap();
     assert!(b == "B".to_string());
     println!("{}", b);
 }
@@ -29,8 +29,8 @@ pub fn main() {
     let (tx, rx) = channel();
     let _child = task::spawn(move|| { start(&tx) });
 
-    let mut c = rx.recv();
-    c.send("A".to_string());
-    c.send("B".to_string());
+    let mut c = rx.recv().unwrap();
+    c.send("A".to_string()).unwrap();
+    c.send("B".to_string()).unwrap();
     task::deschedule();
 }
diff --git a/src/test/run-pass/task-comm-11.rs b/src/test/run-pass/task-comm-11.rs
index aefc91df4e7..8168e84e426 100644
--- a/src/test/run-pass/task-comm-11.rs
+++ b/src/test/run-pass/task-comm-11.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use std::sync::mpsc::{channel, Sender};
 use std::task;
 
 fn start(tx: &Sender<Sender<int>>) {
diff --git a/src/test/run-pass/task-comm-13.rs b/src/test/run-pass/task-comm-13.rs
index c6c0691b749..bb92ef38728 100644
--- a/src/test/run-pass/task-comm-13.rs
+++ b/src/test/run-pass/task-comm-13.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use std::sync::mpsc::{channel, Sender};
 use std::task;
 
 fn start(tx: &Sender<int>, start: int, number_of_messages: int) {
diff --git a/src/test/run-pass/task-comm-14.rs b/src/test/run-pass/task-comm-14.rs
index 0e483813665..d63cbd5c8ba 100644
--- a/src/test/run-pass/task-comm-14.rs
+++ b/src/test/run-pass/task-comm-14.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use std::sync::mpsc::{channel, Sender};
 use std::task;
 
 pub fn main() {
diff --git a/src/test/run-pass/task-comm-15.rs b/src/test/run-pass/task-comm-15.rs
index 3095c2098ff..7c652ddc406 100644
--- a/src/test/run-pass/task-comm-15.rs
+++ b/src/test/run-pass/task-comm-15.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use std::sync::mpsc::{channel, Sender};
 use std::task;
 
 fn start(tx: &Sender<int>, i0: int) {
diff --git a/src/test/run-pass/task-comm-16.rs b/src/test/run-pass/task-comm-16.rs
index ec41019846b..065777bd961 100644
--- a/src/test/run-pass/task-comm-16.rs
+++ b/src/test/run-pass/task-comm-16.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
 use std::cmp;
 
 // Tests of ports and channels on various types
@@ -16,9 +17,9 @@ fn test_rec() {
 
     let (tx, rx) = channel();
     let r0: R = R {val0: 0, val1: 1u8, val2: '2'};
-    tx.send(r0);
+    tx.send(r0).unwrap();
     let mut r1: R;
-    r1 = rx.recv();
+    r1 = rx.recv().unwrap();
     assert_eq!(r1.val0, 0);
     assert_eq!(r1.val1, 1u8);
     assert_eq!(r1.val2, '2');
@@ -27,8 +28,8 @@ fn test_rec() {
 fn test_vec() {
     let (tx, rx) = channel();
     let v0: Vec<int> = vec!(0, 1, 2);
-    tx.send(v0);
-    let v1 = rx.recv();
+    tx.send(v0).unwrap();
+    let v1 = rx.recv().unwrap();
     assert_eq!(v1[0], 0);
     assert_eq!(v1[1], 1);
     assert_eq!(v1[2], 2);
@@ -37,8 +38,8 @@ fn test_vec() {
 fn test_str() {
     let (tx, rx) = channel();
     let s0 = "test".to_string();
-    tx.send(s0);
-    let s1 = rx.recv();
+    tx.send(s0).unwrap();
+    let s1 = rx.recv().unwrap();
     assert_eq!(s1.as_bytes()[0], 't' as u8);
     assert_eq!(s1.as_bytes()[1], 'e' as u8);
     assert_eq!(s1.as_bytes()[2], 's' as u8);
@@ -81,28 +82,28 @@ impl cmp::PartialEq for t {
 
 fn test_tag() {
     let (tx, rx) = channel();
-    tx.send(t::tag1);
-    tx.send(t::tag2(10));
-    tx.send(t::tag3(10, 11u8, 'A'));
+    tx.send(t::tag1).unwrap();
+    tx.send(t::tag2(10)).unwrap();
+    tx.send(t::tag3(10, 11u8, 'A')).unwrap();
     let mut t1: t;
-    t1 = rx.recv();
+    t1 = rx.recv().unwrap();
     assert_eq!(t1, t::tag1);
-    t1 = rx.recv();
+    t1 = rx.recv().unwrap();
     assert_eq!(t1, t::tag2(10));
-    t1 = rx.recv();
+    t1 = rx.recv().unwrap();
     assert_eq!(t1, t::tag3(10, 11u8, 'A'));
 }
 
 fn test_chan() {
     let (tx1, rx1) = channel();
     let (tx2, rx2) = channel();
-    tx1.send(tx2);
-    let tx2 = rx1.recv();
+    tx1.send(tx2).unwrap();
+    let tx2 = rx1.recv().unwrap();
     // Does the transmitted channel still work?
 
-    tx2.send(10);
+    tx2.send(10).unwrap();
     let mut i: int;
-    i = rx2.recv();
+    i = rx2.recv().unwrap();
     assert_eq!(i, 10);
 }
 
diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs
index 73f6eb563c1..a002a597481 100644
--- a/src/test/run-pass/task-comm-3.rs
+++ b/src/test/run-pass/task-comm-3.rs
@@ -11,6 +11,7 @@
 // no-pretty-expanded FIXME #15189
 
 use std::thread::Thread;
+use std::sync::mpsc::{channel, Sender};
 
 pub fn main() { println!("===== WITHOUT THREADS ====="); test00(); }
 
@@ -19,7 +20,7 @@ fn test00_start(ch: &Sender<int>, message: int, count: int) {
     let mut i: int = 0;
     while i < count {
         println!("Sending Message");
-        ch.send(message + 0);
+        ch.send(message + 0).unwrap();
         i = i + 1;
     }
     println!("Ending test00_start");
@@ -53,7 +54,7 @@ fn test00() {
     for _r in results.iter() {
         i = 0;
         while i < number_of_messages {
-            let value = rx.recv();
+            let value = rx.recv().unwrap();
             sum += value;
             i = i + 1;
         }
diff --git a/src/test/run-pass/task-comm-4.rs b/src/test/run-pass/task-comm-4.rs
index 2e2b1fbff0f..1f1b750aa57 100644
--- a/src/test/run-pass/task-comm-4.rs
+++ b/src/test/run-pass/task-comm-4.rs
@@ -10,42 +10,44 @@
 
 #![allow(dead_assignment)]
 
+use std::sync::mpsc::channel;
+
 pub fn main() { test00(); }
 
 fn test00() {
     let mut r: int = 0;
     let mut sum: int = 0;
     let (tx, rx) = channel();
-    tx.send(1);
-    tx.send(2);
-    tx.send(3);
-    tx.send(4);
-    r = rx.recv();
+    tx.send(1).unwrap();
+    tx.send(2).unwrap();
+    tx.send(3).unwrap();
+    tx.send(4).unwrap();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
-    r = rx.recv();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
-    r = rx.recv();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
-    r = rx.recv();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
-    tx.send(5);
-    tx.send(6);
-    tx.send(7);
-    tx.send(8);
-    r = rx.recv();
+    tx.send(5).unwrap();
+    tx.send(6).unwrap();
+    tx.send(7).unwrap();
+    tx.send(8).unwrap();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
-    r = rx.recv();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
-    r = rx.recv();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
-    r = rx.recv();
+    r = rx.recv().unwrap();
     sum += r;
     println!("{}", r);
     assert_eq!(sum, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
diff --git a/src/test/run-pass/task-comm-5.rs b/src/test/run-pass/task-comm-5.rs
index e51e14f7fbe..039308d5cfe 100644
--- a/src/test/run-pass/task-comm-5.rs
+++ b/src/test/run-pass/task-comm-5.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
+
 pub fn main() { test00(); }
 
 fn test00() {
@@ -16,8 +18,8 @@ fn test00() {
     let (tx, rx) = channel();
     let number_of_messages: int = 1000;
     let mut i: int = 0;
-    while i < number_of_messages { tx.send(i + 0); i += 1; }
+    while i < number_of_messages { tx.send(i + 0).unwrap(); i += 1; }
     i = 0;
-    while i < number_of_messages { sum += rx.recv(); i += 1; }
+    while i < number_of_messages { sum += rx.recv().unwrap(); i += 1; }
     assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2);
 }
diff --git a/src/test/run-pass/task-comm-6.rs b/src/test/run-pass/task-comm-6.rs
index e783cd9b6be..7cdfddcdeb1 100644
--- a/src/test/run-pass/task-comm-6.rs
+++ b/src/test/run-pass/task-comm-6.rs
@@ -10,6 +10,8 @@
 
 #![allow(dead_assignment)]
 
+use std::sync::mpsc::channel;
+
 pub fn main() { test00(); }
 
 fn test00() {
@@ -23,21 +25,21 @@ fn test00() {
     let number_of_messages: int = 1000;
     let mut i: int = 0;
     while i < number_of_messages {
-        tx0.send(i + 0);
-        tx1.send(i + 0);
-        tx2.send(i + 0);
-        tx3.send(i + 0);
+        tx0.send(i + 0).unwrap();
+        tx1.send(i + 0).unwrap();
+        tx2.send(i + 0).unwrap();
+        tx3.send(i + 0).unwrap();
         i += 1;
     }
     i = 0;
     while i < number_of_messages {
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
         i += 1;
     }
diff --git a/src/test/run-pass/task-comm-7.rs b/src/test/run-pass/task-comm-7.rs
index 9d8caa42626..054090eca39 100644
--- a/src/test/run-pass/task-comm-7.rs
+++ b/src/test/run-pass/task-comm-7.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 #![allow(dead_assignment)]
 
+use std::sync::mpsc::{channel, Sender};
 use std::task;
 
 pub fn main() { test00(); }
@@ -18,7 +18,7 @@ pub fn main() { test00(); }
 fn test00_start(c: &Sender<int>, start: int,
                 number_of_messages: int) {
     let mut i: int = 0;
-    while i < number_of_messages { c.send(start + i); i += 1; }
+    while i < number_of_messages { c.send(start + i).unwrap(); i += 1; }
 }
 
 fn test00() {
@@ -46,13 +46,13 @@ fn test00() {
 
     let mut i: int = 0;
     while i < number_of_messages {
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
-        r = rx.recv();
+        r = rx.recv().unwrap();
         sum += r;
         i += 1;
     }
diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs
index 69d70050437..d9faf6ee4e4 100644
--- a/src/test/run-pass/task-comm-9.rs
+++ b/src/test/run-pass/task-comm-9.rs
@@ -9,12 +9,13 @@
 // except according to those terms.
 
 use std::thread::Thread;
+use std::sync::mpsc::{channel, Sender};
 
 pub fn main() { test00(); }
 
 fn test00_start(c: &Sender<int>, number_of_messages: int) {
     let mut i: int = 0;
-    while i < number_of_messages { c.send(i + 0); i += 1; }
+    while i < number_of_messages { c.send(i + 0).unwrap(); i += 1; }
 }
 
 fn test00() {
@@ -29,7 +30,7 @@ fn test00() {
 
     let mut i: int = 0;
     while i < number_of_messages {
-        sum += rx.recv();
+        sum += rx.recv().unwrap();
         println!("{}", r);
         i += 1;
     }
diff --git a/src/test/run-pass/task-comm-chan-nil.rs b/src/test/run-pass/task-comm-chan-nil.rs
index 3ea17898ead..78a42632001 100644
--- a/src/test/run-pass/task-comm-chan-nil.rs
+++ b/src/test/run-pass/task-comm-chan-nil.rs
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
+
 // rustboot can't transmit nils across channels because they don't have
 // any size, but rustc currently can because they do have size. Whether
 // or not this is desirable I don't know, but here's a regression test.
 pub fn main() {
     let (tx, rx) = channel();
-    tx.send(());
-    let n: () = rx.recv();
+    tx.send(()).unwrap();
+    let n: () = rx.recv().unwrap();
     assert_eq!(n, ());
 }
diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs
index 8d6b6005a63..623a30eda1a 100644
--- a/src/test/run-pass/task-spawn-move-and-copy.rs
+++ b/src/test/run-pass/task-spawn-move-and-copy.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::task;
+use std::sync::mpsc::channel;
 
 pub fn main() {
     let (tx, rx) = channel::<uint>();
@@ -18,9 +19,9 @@ pub fn main() {
 
     task::spawn(move || {
         let x_in_child = &(*x) as *const int as uint;
-        tx.send(x_in_child);
+        tx.send(x_in_child).unwrap();
     });
 
-    let x_in_child = rx.recv();
+    let x_in_child = rx.recv().unwrap();
     assert_eq!(x_in_parent, x_in_child);
 }
diff --git a/src/test/run-pass/task-stderr.rs b/src/test/run-pass/task-stderr.rs
index ddeffcdf722..a7eabe0edb3 100644
--- a/src/test/run-pass/task-stderr.rs
+++ b/src/test/run-pass/task-stderr.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
 use std::io::{ChanReader, ChanWriter};
 use std::thread;
 
diff --git a/src/test/run-pass/tcp-accept-stress.rs b/src/test/run-pass/tcp-accept-stress.rs
index 780cf234466..07f71fe580e 100644
--- a/src/test/run-pass/tcp-accept-stress.rs
+++ b/src/test/run-pass/tcp-accept-stress.rs
@@ -13,8 +13,10 @@
 //              quite quickly and it takes a few seconds for the sockets to get
 //              recycled.
 
+use std::sync::mpsc::channel;
 use std::io::{TcpListener, Listener, Acceptor, EndOfFile, TcpStream};
 use std::sync::{atomic, Arc};
+use std::thread::Thread;
 
 static N: uint = 8;
 static M: uint = 20;
@@ -35,7 +37,7 @@ fn test() {
         let a = a.clone();
         let cnt = cnt.clone();
         let srv_tx = srv_tx.clone();
-        spawn(move|| {
+        Thread::spawn(move|| {
             let mut a = a;
             loop {
                 match a.accept() {
@@ -49,17 +51,17 @@ fn test() {
                 }
             }
             srv_tx.send(());
-        });
+        }).detach();
     }
 
     for _ in range(0, N) {
         let cli_tx = cli_tx.clone();
-        spawn(move|| {
+        Thread::spawn(move|| {
             for _ in range(0, M) {
                 let _s = TcpStream::connect(addr).unwrap();
             }
             cli_tx.send(());
-        });
+        }).detach();
     }
     drop((cli_tx, srv_tx));
 
diff --git a/src/test/run-pass/tcp-connect-timeouts.rs b/src/test/run-pass/tcp-connect-timeouts.rs
index 2d087406fd6..38a762d5803 100644
--- a/src/test/run-pass/tcp-connect-timeouts.rs
+++ b/src/test/run-pass/tcp-connect-timeouts.rs
@@ -26,6 +26,7 @@ use std::io::*;
 use std::io::test::*;
 use std::io;
 use std::time::Duration;
+use std::sync::mpsc::channel;
 
 #[cfg_attr(target_os = "freebsd", ignore)]
 fn eventual_timeout() {
@@ -35,10 +36,10 @@ fn eventual_timeout() {
     let (_tx2, rx2) = channel::<()>();
     std::task::spawn(move|| {
         let _l = TcpListener::bind(addr).unwrap().listen();
-        tx1.send(());
-        let _ = rx2.recv_opt();
+        tx1.send(()).unwrap();
+        let _ = rx2.recv();
     });
-    rx1.recv();
+    rx1.recv().unwrap();
 
     let mut v = Vec::new();
     for _ in range(0u, 10000) {
diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs
index b3391669d35..62b61c153c7 100644
--- a/src/test/run-pass/tcp-stress.rs
+++ b/src/test/run-pass/tcp-stress.rs
@@ -17,24 +17,25 @@
 extern crate log;
 extern crate libc;
 
+use std::sync::mpsc::channel;
 use std::io::net::tcp::{TcpListener, TcpStream};
 use std::io::{Acceptor, Listener};
-use std::thread::Builder;
+use std::thread::{Builder, Thread};
 use std::time::Duration;
 
 fn main() {
     // This test has a chance to time out, try to not let it time out
-    spawn(move|| {
+    Thread::spawn(move|| -> () {
         use std::io::timer;
         timer::sleep(Duration::milliseconds(30 * 1000));
         println!("timed out!");
         unsafe { libc::exit(1) }
-    });
+    }).detach();
 
     let (tx, rx) = channel();
-    spawn(move|| {
+    Thread::spawn(move || -> () {
         let mut listener = TcpListener::bind("127.0.0.1:0").unwrap();
-        tx.send(listener.socket_name().unwrap());
+        tx.send(listener.socket_name().unwrap()).unwrap();
         let mut acceptor = listener.listen();
         loop {
             let mut stream = match acceptor.accept() {
@@ -47,8 +48,8 @@ fn main() {
             stream.read_byte();
             stream.write(&[2]);
         }
-    });
-    let addr = rx.recv();
+    }).detach();
+    let addr = rx.recv().unwrap();
 
     let (tx, rx) = channel();
     for _ in range(0u, 1000) {
@@ -63,7 +64,7 @@ fn main() {
                 },
                 Err(e) => debug!("{}", e)
             }
-            tx.send(());
+            tx.send(()).unwrap();
         }).detach();
     }
 
@@ -71,7 +72,7 @@ fn main() {
     // server just runs infinitely.
     drop(tx);
     for _ in range(0u, 1000) {
-        rx.recv();
+        rx.recv().unwrap();
     }
     unsafe { libc::exit(0) }
 }
diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs
index a866f497b86..9e67095bb30 100644
--- a/src/test/run-pass/tempfile.rs
+++ b/src/test/run-pass/tempfile.rs
@@ -23,6 +23,7 @@ use std::io::{fs, TempDir};
 use std::io;
 use std::os;
 use std::task;
+use std::sync::mpsc::channel;
 
 fn test_tempdir() {
     let path = {
@@ -38,11 +39,11 @@ fn test_rm_tempdir() {
     let (tx, rx) = channel();
     let f = move|:| -> () {
         let tmp = TempDir::new("test_rm_tempdir").unwrap();
-        tx.send(tmp.path().clone());
+        tx.send(tmp.path().clone()).unwrap();
         panic!("panic to unwind past `tmp`");
     };
     task::try(f);
-    let path = rx.recv();
+    let path = rx.recv().unwrap();
     assert!(!path.exists());
 
     let tmp = TempDir::new("test_rm_tempdir").unwrap();
@@ -79,12 +80,12 @@ fn test_rm_tempdir_close() {
     let (tx, rx) = channel();
     let f = move|:| -> () {
         let tmp = TempDir::new("test_rm_tempdir").unwrap();
-        tx.send(tmp.path().clone());
+        tx.send(tmp.path().clone()).unwrap();
         tmp.close();
         panic!("panic when unwinding past `tmp`");
     };
     task::try(f);
-    let path = rx.recv();
+    let path = rx.recv().unwrap();
     assert!(!path.exists());
 
     let tmp = TempDir::new("test_rm_tempdir").unwrap();
diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs
index d2c1461d65d..0d2cb60c213 100644
--- a/src/test/run-pass/trait-bounds-in-arc.rs
+++ b/src/test/run-pass/trait-bounds-in-arc.rs
@@ -11,8 +11,8 @@
 // Tests that a heterogeneous list of existential types can be put inside an Arc
 // and shared between tasks as long as all types fulfill Send.
 
-
 use std::sync::Arc;
+use std::sync::mpsc::channel;
 use std::task;
 
 trait Pet {
diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs
index 216a7ef33f5..003686c0bbe 100644
--- a/src/test/run-pass/trait-impl.rs
+++ b/src/test/run-pass/trait-impl.rs
@@ -10,6 +10,10 @@
 
 // Test calling methods on an impl for a bare trait.
 
+// aux-build:traitimpl.rs
+extern crate traitimpl;
+use traitimpl::Bar;
+
 static mut COUNT: uint = 1;
 
 trait T {}
@@ -25,6 +29,9 @@ impl<'a> T+'a {
 
 impl T for int {}
 
+struct Foo;
+impl<'a> Bar<'a> for Foo {}
+
 fn main() {
     let x: &T = &42i;
 
@@ -33,4 +40,8 @@ fn main() {
     T::bar();
 
     unsafe { assert!(COUNT == 12); }
+
+    // Cross-crait case
+    let x: &Bar = &Foo;
+    x.bar();
 }
diff --git a/src/test/run-pass/trait-inheritance-overloading.rs b/src/test/run-pass/trait-inheritance-overloading.rs
index 739c3e4bdb0..3748a31b302 100644
--- a/src/test/run-pass/trait-inheritance-overloading.rs
+++ b/src/test/run-pass/trait-inheritance-overloading.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::cmp::PartialEq;
+use std::ops::{Add, Sub, Mul};
 
 trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq + Clone { }
 
diff --git a/src/test/run-pass/trivial-message.rs b/src/test/run-pass/trivial-message.rs
index 464ab135228..6bece8265c0 100644
--- a/src/test/run-pass/trivial-message.rs
+++ b/src/test/run-pass/trivial-message.rs
@@ -13,6 +13,8 @@
   message.
  */
 
+use std::sync::mpsc::channel;
+
 pub fn main() {
     let (tx, rx) = channel();
     tx.send(42i);
diff --git a/src/test/run-pass/unboxed-closures-call-sugar-object.rs b/src/test/run-pass/unboxed-closures-call-sugar-object.rs
new file mode 100644
index 00000000000..2dec53cc13a
--- /dev/null
+++ b/src/test/run-pass/unboxed-closures-call-sugar-object.rs
@@ -0,0 +1,25 @@
+// 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.
+
+#![feature(unboxed_closures)]
+
+use std::ops::FnMut;
+
+fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
+    box move |y| { x + y }
+}
+
+pub fn main() {
+    let mut adder = make_adder(3);
+    let z = (*adder)(2);
+    println!("{}", z);
+    assert_eq!(z, 5);
+}
+
diff --git a/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-bound.rs b/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-bound.rs
index 465c324122a..fdd85b71cd2 100644
--- a/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-bound.rs
+++ b/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-bound.rs
@@ -13,6 +13,8 @@
 
 #![feature(unboxed_closures)]
 
+use std::num::ToPrimitive;
+
 fn doit<T,F>(val: T, f: &F)
     where F : Fn(T)
 {
diff --git a/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-object-type.rs b/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-object-type.rs
index 440292d202e..cce8cd64a14 100644
--- a/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-object-type.rs
+++ b/src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-object-type.rs
@@ -13,6 +13,8 @@
 
 #![feature(unboxed_closures)]
 
+use std::num::ToPrimitive;
+
 fn doit<T>(val: T, f: &Fn(T)) { f.call((val,)) }
 
 pub fn main() {
diff --git a/src/test/run-pass/unboxed-closures-infer-argument-types-with-bound-regions-from-expected-bound.rs b/src/test/run-pass/unboxed-closures-infer-argument-types-with-bound-regions-from-expected-bound.rs
index b279eb5fbba..8497bf7f987 100644
--- a/src/test/run-pass/unboxed-closures-infer-argument-types-with-bound-regions-from-expected-bound.rs
+++ b/src/test/run-pass/unboxed-closures-infer-argument-types-with-bound-regions-from-expected-bound.rs
@@ -13,6 +13,8 @@
 
 #![feature(unboxed_closures)]
 
+use std::num::ToPrimitive;
+
 fn doit<T,F>(val: T, f: &F)
     where F : Fn(&T)
 {
diff --git a/src/test/run-pass/unique-send-2.rs b/src/test/run-pass/unique-send-2.rs
index 672cd2d00e8..f88c458f2ed 100644
--- a/src/test/run-pass/unique-send-2.rs
+++ b/src/test/run-pass/unique-send-2.rs
@@ -9,9 +9,10 @@
 // except according to those terms.
 
 use std::task;
+use std::sync::mpsc::{channel, Sender};
 
 fn child(tx: &Sender<Box<uint>>, i: uint) {
-    tx.send(box i);
+    tx.send(box i).unwrap();
 }
 
 pub fn main() {
@@ -28,7 +29,7 @@ pub fn main() {
 
     let mut actual = 0u;
     for _ in range(0u, n) {
-        let j = rx.recv();
+        let j = rx.recv().unwrap();
         actual += *j;
     }
 
diff --git a/src/test/run-pass/unique-send.rs b/src/test/run-pass/unique-send.rs
index 22b5a8cdaa4..afafb204c1c 100644
--- a/src/test/run-pass/unique-send.rs
+++ b/src/test/run-pass/unique-send.rs
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::sync::mpsc::channel;
+
 pub fn main() {
     let (tx, rx) = channel();
-    tx.send(box 100i);
-    let v = rx.recv();
+    tx.send(box 100i).unwrap();
+    let v = rx.recv().unwrap();
     assert_eq!(v, box 100i);
 }
diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs
index 9789deef636..943b2d3edd1 100644
--- a/src/test/run-pass/unwind-resource.rs
+++ b/src/test/run-pass/unwind-resource.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use std::sync::mpsc::{channel, Sender};
 use std::task;
 
 struct complainer {
@@ -18,7 +18,7 @@ struct complainer {
 impl Drop for complainer {
     fn drop(&mut self) {
         println!("About to send!");
-        self.tx.send(true);
+        self.tx.send(true).unwrap();
         println!("Sent!");
     }
 }
@@ -39,5 +39,5 @@ pub fn main() {
     let (tx, rx) = channel();
     task::spawn(move|| f(tx.clone()));
     println!("hiiiiiiiii");
-    assert!(rx.recv());
+    assert!(rx.recv().unwrap());
 }
diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs
index f8eef988561..ec320c1f8a3 100644
--- a/src/test/run-pass/variadic-ffi.rs
+++ b/src/test/run-pass/variadic-ffi.rs
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 extern crate libc;
-use std::c_str::CString;
+
+use std::c_str::{CString, ToCStr};
 use libc::{c_char, c_int};
 
 // ignore-fast doesn't like extern crate
diff --git a/src/test/run-pass/vector-sort-panic-safe.rs b/src/test/run-pass/vector-sort-panic-safe.rs
index 08bd367917a..2da0ecd6d51 100644
--- a/src/test/run-pass/vector-sort-panic-safe.rs
+++ b/src/test/run-pass/vector-sort-panic-safe.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::task;
-use std::sync::atomic::{AtomicUint, INIT_ATOMIC_UINT, Relaxed};
+use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Relaxed};
 use std::rand::{thread_rng, Rng, Rand};
 
 const REPEATS: uint = 5;
@@ -17,18 +17,18 @@ const MAX_LEN: uint = 32;
 static drop_counts: [AtomicUint;  MAX_LEN] =
     // FIXME #5244: AtomicUint is not Copy.
     [
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
 
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
-        INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT, INIT_ATOMIC_UINT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
+        ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT, ATOMIC_UINT_INIT,
      ];
 
-static creation_count: AtomicUint = INIT_ATOMIC_UINT;
+static creation_count: AtomicUint = ATOMIC_UINT_INIT;
 
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord)]
 struct DropCounter { x: uint, creation_id: uint }
diff --git a/src/test/run-pass/wait-forked-but-failed-child.rs b/src/test/run-pass/wait-forked-but-failed-child.rs
index 577e114945c..624b4176704 100644
--- a/src/test/run-pass/wait-forked-but-failed-child.rs
+++ b/src/test/run-pass/wait-forked-but-failed-child.rs
@@ -12,10 +12,10 @@ extern crate libc;
 
 use std::io::process::Command;
 use std::iter::IteratorExt;
+use std::str::from_str;
 
 use libc::funcs::posix88::unistd;
 
-
 // The output from "ps -A -o pid,ppid,args" should look like this:
 //   PID  PPID COMMAND
 //     1     0 /sbin/init