about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--.travis.yml3
-rw-r--r--RELEASES.md19
-rwxr-xr-xconfigure41
-rw-r--r--mk/cfg/aarch64-linux-android.mk8
-rw-r--r--mk/cfg/arm-linux-androideabi.mk8
-rw-r--r--mk/ctags.mk23
-rw-r--r--mk/docs.mk9
-rw-r--r--mk/tests.mk3
-rw-r--r--src/doc/nomicon/README.md38
-rw-r--r--src/doc/nomicon/SUMMARY.md53
-rw-r--r--src/doc/nomicon/arc-and-mutex.md7
-rw-r--r--src/doc/nomicon/atomics.md255
-rw-r--r--src/doc/nomicon/borrow-splitting.md291
-rw-r--r--src/doc/nomicon/casts.md71
-rw-r--r--src/doc/nomicon/checked-uninit.md117
-rw-r--r--src/doc/nomicon/coercions.md70
-rw-r--r--src/doc/nomicon/concurrency.md13
-rw-r--r--src/doc/nomicon/constructors.md59
-rw-r--r--src/doc/nomicon/conversions.md34
-rw-r--r--src/doc/nomicon/data.md5
-rw-r--r--src/doc/nomicon/destructors.md181
-rw-r--r--src/doc/nomicon/dot-operator.md6
-rw-r--r--src/doc/nomicon/drop-flags.md95
-rw-r--r--src/doc/nomicon/dropck.md127
-rw-r--r--src/doc/nomicon/exception-safety.md217
-rw-r--r--src/doc/nomicon/exotic-sizes.md137
-rw-r--r--src/doc/nomicon/hrtb.md73
-rw-r--r--src/doc/nomicon/leaking.md252
-rw-r--r--src/doc/nomicon/lifetime-elision.md64
-rw-r--r--src/doc/nomicon/lifetime-mismatch.md81
-rw-r--r--src/doc/nomicon/lifetimes.md216
-rw-r--r--src/doc/nomicon/meet-safe-and-unsafe.md98
-rw-r--r--src/doc/nomicon/obrm.md14
-rw-r--r--src/doc/nomicon/other-reprs.md76
-rw-r--r--src/doc/nomicon/ownership.md67
-rw-r--r--src/doc/nomicon/phantom-data.md87
-rw-r--r--src/doc/nomicon/poisoning.md35
-rw-r--r--src/doc/nomicon/races.md86
-rw-r--r--src/doc/nomicon/references.md177
-rw-r--r--src/doc/nomicon/repr-rust.md152
-rw-r--r--src/doc/nomicon/safe-unsafe-meaning.md150
-rw-r--r--src/doc/nomicon/send-and-sync.md80
-rw-r--r--src/doc/nomicon/subtyping.md212
-rw-r--r--src/doc/nomicon/transmutes.md35
-rw-r--r--src/doc/nomicon/unbounded-lifetimes.md37
-rw-r--r--src/doc/nomicon/unchecked-uninit.md85
-rw-r--r--src/doc/nomicon/uninitialized.md10
-rw-r--r--src/doc/nomicon/unwinding.md49
-rw-r--r--src/doc/nomicon/vec-alloc.md222
-rw-r--r--src/doc/nomicon/vec-dealloc.md29
-rw-r--r--src/doc/nomicon/vec-deref.md42
-rw-r--r--src/doc/nomicon/vec-drain.md150
-rw-r--r--src/doc/nomicon/vec-final.md311
-rw-r--r--src/doc/nomicon/vec-insert-remove.md51
-rw-r--r--src/doc/nomicon/vec-into-iter.md147
-rw-r--r--src/doc/nomicon/vec-layout.md100
-rw-r--r--src/doc/nomicon/vec-push-pop.md55
-rw-r--r--src/doc/nomicon/vec-raw.md136
-rw-r--r--src/doc/nomicon/vec-zsts.md176
-rw-r--r--src/doc/nomicon/vec.md20
-rw-r--r--src/doc/nomicon/working-with-unsafe.md119
-rw-r--r--src/doc/reference.md4
-rw-r--r--src/doc/trpl/SUMMARY.md3
-rw-r--r--src/doc/trpl/choosing-your-guarantees.md11
-rw-r--r--src/doc/trpl/compiler-plugins.md5
-rw-r--r--src/doc/trpl/concurrency.md12
-rw-r--r--src/doc/trpl/crates-and-modules.md7
-rw-r--r--src/doc/trpl/for-loops.md85
-rw-r--r--src/doc/trpl/glossary.md58
-rw-r--r--src/doc/trpl/guessing-game.md6
-rw-r--r--src/doc/trpl/hello-cargo.md36
-rw-r--r--src/doc/trpl/hello-world.md11
-rw-r--r--src/doc/trpl/intrinsics.md2
-rw-r--r--src/doc/trpl/lang-items.md1
-rw-r--r--src/doc/trpl/loops.md209
-rw-r--r--src/doc/trpl/no-stdlib.md3
-rw-r--r--src/doc/trpl/patterns.md79
-rw-r--r--src/doc/trpl/the-stack-and-the-heap.md4
-rw-r--r--src/doc/trpl/while-loops.md111
-rw-r--r--src/etc/ctags.rust6
-rw-r--r--src/liballoc/arc.rs48
-rw-r--r--src/liballoc/boxed.rs80
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/liballoc/rc.rs55
-rw-r--r--src/libcollections/binary_heap.rs24
-rw-r--r--src/libcollections/bit.rs147
-rw-r--r--src/libcollections/btree/map.rs6
-rw-r--r--src/libcollections/btree/set.rs3
-rw-r--r--src/libcollections/fmt.rs22
-rw-r--r--src/libcollections/lib.rs2
-rw-r--r--src/libcollections/linked_list.rs6
-rw-r--r--src/libcollections/slice.rs18
-rw-r--r--src/libcollections/str.rs61
-rw-r--r--src/libcollections/string.rs5
-rw-r--r--src/libcollections/vec.rs26
-rw-r--r--src/libcollections/vec_deque.rs72
-rw-r--r--src/libcollections/vec_map.rs70
-rw-r--r--src/libcollectionstest/slice.rs53
-rw-r--r--src/libcollectionstest/str.rs8
-rw-r--r--src/libcore/atomic.rs5
-rw-r--r--src/libcore/cell.rs6
-rw-r--r--src/libcore/cmp.rs12
-rw-r--r--src/libcore/fmt/num.rs3
-rw-r--r--src/libcore/hash/mod.rs29
-rw-r--r--src/libcore/iter.rs21
-rw-r--r--src/libcore/lib.rs33
-rw-r--r--src/libcore/macros.rs4
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/mem.rs76
-rw-r--r--src/libcore/num/mod.rs8
-rw-r--r--src/libcore/option.rs3
-rw-r--r--src/libcore/ptr.rs2
-rw-r--r--src/libcore/raw.rs6
-rw-r--r--src/libcore/result.rs3
-rw-r--r--src/libcore/simd.rs3
-rw-r--r--src/libcore/slice.rs9
-rw-r--r--src/libcore/str/pattern.rs2
-rw-r--r--src/libgraphviz/lib.rs9
-rw-r--r--src/liblibc/lib.rs11
-rw-r--r--src/librustc/ast_map/mod.rs13
-rw-r--r--src/librustc/diagnostics.rs6
-rw-r--r--src/librustc/lint/context.rs17
-rw-r--r--src/librustc/metadata/creader.rs12
-rw-r--r--src/librustc/metadata/decoder.rs23
-rw-r--r--src/librustc/metadata/encoder.rs36
-rw-r--r--src/librustc/metadata/macro_import.rs8
-rw-r--r--src/librustc/metadata/tyencode.rs13
-rw-r--r--src/librustc/middle/astencode.rs13
-rw-r--r--src/librustc/middle/check_const.rs11
-rw-r--r--src/librustc/middle/check_match.rs9
-rw-r--r--src/librustc/middle/check_static_recursion.rs2
-rw-r--r--src/librustc/middle/const_eval.rs15
-rw-r--r--src/librustc/middle/def.rs24
-rw-r--r--src/librustc/middle/infer/error_reporting.rs14
-rw-r--r--src/librustc/middle/intrinsicck.rs7
-rw-r--r--src/librustc/middle/lang_items.rs1
-rw-r--r--src/librustc/middle/liveness.rs4
-rw-r--r--src/librustc/middle/resolve_lifetime.rs8
-rw-r--r--src/librustc/middle/stability.rs2
-rw-r--r--src/librustc/middle/ty.rs50
-rw-r--r--src/librustc/middle/weak_lang_items.rs5
-rw-r--r--src/librustc/session/config.rs16
-rw-r--r--src/librustc_back/svh.rs28
-rw-r--r--src/librustc_back/target/mod.rs6
-rw-r--r--src/librustc_back/target/x86_64_pc_windows_gnu.rs1
-rw-r--r--src/librustc_bitflags/lib.rs6
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs3
-rw-r--r--src/librustc_borrowck/diagnostics.rs23
-rw-r--r--src/librustc_driver/lib.rs2
-rw-r--r--src/librustc_driver/pretty.rs4
-rw-r--r--src/librustc_lint/builtin.rs101
-rw-r--r--src/librustc_privacy/lib.rs12
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs28
-rw-r--r--src/librustc_resolve/diagnostics.rs17
-rw-r--r--src/librustc_resolve/lib.rs82
-rw-r--r--src/librustc_resolve/record_exports.rs3
-rw-r--r--src/librustc_resolve/resolve_imports.rs13
-rw-r--r--src/librustc_trans/back/link.rs2
-rw-r--r--src/librustc_trans/back/msvc/mod.rs43
-rw-r--r--src/librustc_trans/save/dump_csv.rs20
-rw-r--r--src/librustc_trans/save/mod.rs33
-rw-r--r--src/librustc_trans/trans/base.rs40
-rw-r--r--src/librustc_trans/trans/callee.rs25
-rw-r--r--src/librustc_trans/trans/cleanup.rs2
-rw-r--r--src/librustc_trans/trans/common.rs51
-rw-r--r--src/librustc_trans/trans/consts.rs14
-rw-r--r--src/librustc_trans/trans/context.rs6
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs95
-rw-r--r--src/librustc_trans/trans/debuginfo/mod.rs10
-rw-r--r--src/librustc_trans/trans/debuginfo/namespace.rs8
-rw-r--r--src/librustc_trans/trans/debuginfo/type_names.rs10
-rw-r--r--src/librustc_trans/trans/expr.rs22
-rw-r--r--src/librustc_trans/trans/foreign.rs3
-rw-r--r--src/librustc_trans/trans/intrinsic.rs163
-rw-r--r--src/librustc_trans/trans/meth.rs3
-rw-r--r--src/librustc_typeck/astconv.rs34
-rw-r--r--src/librustc_typeck/check/_match.rs9
-rw-r--r--src/librustc_typeck/check/cast.rs28
-rw-r--r--src/librustc_typeck/check/compare_method.rs11
-rw-r--r--src/librustc_typeck/check/dropck.rs443
-rw-r--r--src/librustc_typeck/check/method/mod.rs17
-rw-r--r--src/librustc_typeck/check/mod.rs92
-rw-r--r--src/librustc_typeck/check/op.rs2
-rw-r--r--src/librustc_typeck/check/regionck.rs2
-rw-r--r--src/librustc_typeck/check/wf.rs4
-rw-r--r--src/librustc_typeck/coherence/mod.rs4
-rw-r--r--src/librustc_typeck/collect.rs5
-rw-r--r--src/librustc_typeck/diagnostics.rs206
-rw-r--r--src/librustc_unicode/char.rs12
-rw-r--r--src/librustc_unicode/u_str.rs3
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs22
-rw-r--r--src/librustdoc/html/highlight.rs4
-rw-r--r--src/librustdoc/html/layout.rs4
-rw-r--r--src/librustdoc/html/static/main.js34
-rw-r--r--src/librustdoc/markdown.rs7
-rw-r--r--src/libserialize/collection_impls.rs3
-rw-r--r--src/libserialize/hex.rs6
-rw-r--r--src/libstd/ascii.rs6
-rw-r--r--src/libstd/collections/hash/map.rs9
-rw-r--r--src/libstd/collections/hash/set.rs6
-rw-r--r--src/libstd/error.rs102
-rw-r--r--src/libstd/ffi/c_str.rs10
-rw-r--r--src/libstd/io/buffered.rs4
-rw-r--r--src/libstd/io/cursor.rs6
-rw-r--r--src/libstd/io/error.rs15
-rw-r--r--src/libstd/io/mod.rs7
-rw-r--r--src/libstd/io/stdio.rs2
-rw-r--r--src/libstd/io/util.rs4
-rw-r--r--src/libstd/lib.rs59
-rw-r--r--src/libstd/macros.rs3
-rw-r--r--src/libstd/net/mod.rs3
-rw-r--r--src/libstd/net/tcp.rs6
-rw-r--r--src/libstd/net/udp.rs18
-rw-r--r--src/libstd/num/f32.rs18
-rw-r--r--src/libstd/num/f64.rs11
-rw-r--r--src/libstd/os/freebsd/raw.rs191
-rw-r--r--src/libstd/prelude/mod.rs6
-rw-r--r--src/libstd/primitive_docs.rs3
-rw-r--r--src/libstd/process.rs17
-rw-r--r--src/libstd/rt/dwarf/eh.rs159
-rw-r--r--src/libstd/rt/dwarf/mod.rs107
-rw-r--r--src/libstd/rt/libunwind.rs2
-rw-r--r--src/libstd/rt/macros.rs4
-rw-r--r--src/libstd/rt/mod.rs4
-rw-r--r--src/libstd/rt/unwind/gcc.rs145
-rw-r--r--src/libstd/rt/unwind/mod.rs17
-rw-r--r--src/libstd/rt/unwind/seh64_gnu.rs227
-rw-r--r--src/libstd/rt/util.rs32
-rw-r--r--src/libstd/sync/condvar.rs3
-rw-r--r--src/libstd/sync/future.rs3
-rw-r--r--src/libstd/sync/mpsc/mod.rs4
-rw-r--r--src/libstd/sync/mpsc/select.rs6
-rw-r--r--src/libstd/sync/mutex.rs3
-rw-r--r--src/libstd/sync/rwlock.rs3
-rw-r--r--src/libstd/sync/semaphore.rs3
-rw-r--r--src/libstd/sys/unix/condvar.rs27
-rw-r--r--src/libstd/sys/unix/ext/process.rs16
-rw-r--r--src/libstd/sys/unix/process.rs6
-rw-r--r--src/libstd/thread/local.rs16
-rw-r--r--src/libstd/thread/mod.rs6
-rw-r--r--src/libstd/thread/scoped_tls.rs31
-rw-r--r--src/libsyntax/ast.rs34
-rw-r--r--src/libsyntax/ast_util.rs4
-rw-r--r--src/libsyntax/diagnostic.rs58
-rw-r--r--src/libsyntax/diagnostics/plugin.rs25
-rw-r--r--src/libsyntax/ext/build.rs3
-rw-r--r--src/libsyntax/ext/concat_idents.rs4
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs16
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs8
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs11
-rw-r--r--src/libsyntax/ext/deriving/show.rs6
-rw-r--r--src/libsyntax/ext/expand.rs60
-rw-r--r--src/libsyntax/ext/format.rs3
-rw-r--r--src/libsyntax/ext/quote.rs4
-rw-r--r--src/libsyntax/ext/source_util.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs12
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs19
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs10
-rw-r--r--src/libsyntax/feature_gate.rs14
-rw-r--r--src/libsyntax/parse/lexer/mod.rs16
-rw-r--r--src/libsyntax/parse/mod.rs53
-rw-r--r--src/libsyntax/parse/obsolete.rs33
-rw-r--r--src/libsyntax/parse/parser.rs44
-rw-r--r--src/libsyntax/parse/token.rs26
-rw-r--r--src/libsyntax/print/pprust.rs32
-rw-r--r--src/libsyntax/std_inject.rs3
-rw-r--r--src/libtest/lib.rs9
-rw-r--r--src/rt/msvc/inttypes.h305
-rw-r--r--src/rt/msvc/stdint.h247
-rw-r--r--src/rt/msvc/typeof.h96
-rw-r--r--src/rt/rust_builtin.c9
-rw-r--r--src/rt/valgrind/memcheck.h285
-rw-r--r--src/rt/valgrind/valgrind.h5414
-rw-r--r--src/snapshots.txt1
-rw-r--r--src/test/auxiliary/lang-item-public.rs3
-rw-r--r--src/test/auxiliary/lint_group_plugin_test.rs10
-rw-r--r--src/test/auxiliary/lint_plugin_test.rs4
-rw-r--r--src/test/auxiliary/roman_numerals.rs4
-rw-r--r--src/test/auxiliary/xcrate_associated_type_defaults.rs2
-rw-r--r--src/test/codegen/link_section.rs36
-rw-r--r--src/test/compile-fail/associated-types-overridden-default.rs1
-rw-r--r--src/test/compile-fail/bad-expr-lhs.rs10
-rw-r--r--src/test/compile-fail/bad-lint-cap.rs14
-rw-r--r--src/test/compile-fail/bad-lint-cap2.rs17
-rw-r--r--src/test/compile-fail/bad-lint-cap3.rs20
-rw-r--r--src/test/compile-fail/cast-as-bool.rs7
-rw-r--r--src/test/compile-fail/cast-rfc0401.rs82
-rw-r--r--src/test/compile-fail/const-cast-different-types.rs4
-rw-r--r--src/test/compile-fail/dropck_misc_variants.rs47
-rw-r--r--src/test/compile-fail/enum-to-float-cast-2.rs4
-rw-r--r--src/test/compile-fail/enum-to-float-cast.rs4
-rw-r--r--src/test/compile-fail/fat-ptr-cast.rs12
-rw-r--r--src/test/compile-fail/feature-gate-assoc-type-defaults.rs15
-rw-r--r--src/test/compile-fail/infinite-tag-type-recursion.rs2
-rw-r--r--src/test/compile-fail/issue-13407.rs2
-rw-r--r--src/test/compile-fail/issue-14845.rs4
-rw-r--r--src/test/compile-fail/issue-17431-1.rs2
-rw-r--r--src/test/compile-fail/issue-17431-2.rs4
-rw-r--r--src/test/compile-fail/issue-17431-3.rs2
-rw-r--r--src/test/compile-fail/issue-17431-4.rs2
-rw-r--r--src/test/compile-fail/issue-17431-5.rs2
-rw-r--r--src/test/compile-fail/issue-17431-6.rs2
-rw-r--r--src/test/compile-fail/issue-17431-7.rs2
-rw-r--r--src/test/compile-fail/issue-17444.rs3
-rw-r--r--src/test/compile-fail/issue-21554.rs4
-rw-r--r--src/test/compile-fail/issue-23073.rs2
-rw-r--r--src/test/compile-fail/issue-23595-1.rs2
-rw-r--r--src/test/compile-fail/issue-23595-2.rs2
-rw-r--r--src/test/compile-fail/issue-27033.rs22
-rw-r--r--src/test/compile-fail/issue-2718-a.rs2
-rw-r--r--src/test/compile-fail/issue-3008-1.rs2
-rw-r--r--src/test/compile-fail/issue-3008-2.rs2
-rw-r--r--src/test/compile-fail/issue-3008-3.rs2
-rw-r--r--src/test/compile-fail/issue-3779.rs2
-rw-r--r--src/test/compile-fail/issue-6702.rs2
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs1
-rw-r--r--src/test/compile-fail/lint-unconditional-recursion.rs66
-rw-r--r--src/test/compile-fail/no_owned_box_lang_item.rs1
-rw-r--r--src/test/compile-fail/old-suffixes-are-really-forbidden.rs4
-rw-r--r--src/test/compile-fail/recursive-enum.rs2
-rw-r--r--src/test/compile-fail/regions-name-static.rs2
-rw-r--r--src/test/compile-fail/type-recursive.rs2
-rw-r--r--src/test/compile-fail/typeck-cast-pointer-to-float.rs3
-rw-r--r--src/test/compile-fail/unboxed-closure-feature-gate.rs2
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-not-used-on-fn.rs4
-rw-r--r--src/test/compile-fail/unsupported-cast.rs2
-rw-r--r--src/test/compile-fail/vector-cast-weirdness.rs2
-rw-r--r--src/test/debuginfo/basic-types-metadata.rs18
-rw-r--r--src/test/debuginfo/gdb-pretty-struct-and-enums.rs188
-rw-r--r--src/test/parse-fail/bad-lit-suffixes.rs32
-rw-r--r--src/test/parse-fail/byte-literals.rs2
-rw-r--r--src/test/parse-fail/byte-string-literals.rs2
-rw-r--r--src/test/parse-fail/empty-impl-semicolon.rs2
-rw-r--r--src/test/parse-fail/issue-23620-invalid-escapes.rs14
-rw-r--r--src/test/parse-fail/issue-27255.rs15
-rw-r--r--src/test/parse-fail/issue-8537.rs2
-rw-r--r--src/test/parse-fail/multitrait.rs2
-rw-r--r--src/test/parse-fail/new-unicode-escapes-3.rs2
-rw-r--r--src/test/parse-fail/new-unicode-escapes-4.rs6
-rw-r--r--src/test/parse-fail/raw-str-delim.rs2
-rw-r--r--src/test/parse-fail/trait-bounds-not-on-impl.rs2
-rw-r--r--src/test/run-make/c-link-to-rust-staticlib/Makefile2
-rw-r--r--src/test/run-make/graphviz-flowgraph/Makefile2
-rw-r--r--src/test/run-make/no-duplicate-libs/bar.rs1
-rw-r--r--src/test/run-make/no-duplicate-libs/foo.rs2
-rw-r--r--src/test/run-pass/default-associated-types.rs2
-rw-r--r--src/test/run-pass/issue-24086.rs29
-rw-r--r--src/test/run-pass/issue-25339.rs2
-rw-r--r--src/test/run-pass/issue-26641.rs15
-rw-r--r--src/test/run-pass/issue-27240.rs33
-rw-r--r--src/test/run-pass/lint-cap.rs18
-rw-r--r--src/test/run-pass/smallest-hello-world.rs1
-rw-r--r--src/test/run-pass/sync-send-atomics.rs22
355 files changed, 9637 insertions, 8771 deletions
diff --git a/.gitattributes b/.gitattributes
index d80daa346ef..0319b4d2f2a 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -6,6 +6,4 @@
 *.rs rust
 src/etc/pkg/rust-logo.ico binary
 src/etc/pkg/rust-logo.png binary
-src/rt/msvc/* -whitespace
-src/rt/valgrind/* -whitespace
 *.woff binary
diff --git a/.travis.yml b/.travis.yml
index dc955bc2f2b..10545b90974 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,8 +20,7 @@ sudo: false
 before_script:
   - ./configure --enable-ccache
 script:
-  - make tidy
-  - make rustc-stage1 -j4
+  - make tidy check -j4
 
 env:
   - CXX=/usr/bin/g++-4.7
diff --git a/RELEASES.md b/RELEASES.md
index db1c7380a78..1dfd2186e13 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -16,6 +16,12 @@ Highlights
   jobs). It's not enabled by default, but will be "in the near
   future". It can be activated with the `-C codegen-units=N` flag to
   `rustc`.
+* This is the first release with [experimental support for linking
+  with the MSVC linker and lib C on Windows (instead of using the GNU
+  variants via MinGW)][win]. It is yet recommended only for the most
+  intrepid Rusticians.
+* Benchmark compilations are showing a 30% improvement in
+  bootstrapping over 1.1.
 
 Breaking Changes
 ----------------
@@ -31,6 +37,10 @@ Breaking Changes
 * [The `#[packed]` attribute is no longer silently accepted by the
   compiler][packed]. This attribute did nothing and code that
   mentioned it likely did not work as intended.
+* Associated type defaults are [now behind the
+  `associated_type_defaults` feature gate][ad]. In 1.1 associated type
+  defaults *did not work*, but could be mentioned syntactically. As
+  such this breakage has minimal impact.
 
 Language
 --------
@@ -46,12 +56,11 @@ Libraries
   `LinkedList`, `VecDeque`, `EnumSet`, `BinaryHeap`, `VecMap`,
   `BTreeSet` and `BTreeMap`. [RFC][extend-rfc].
 * The [`iter::once`] function returns an iterator that yields a single
-  element.
-* The [`iter::empty`] function returns an iterator that yields no
+  element, and [`iter::empty`] returns an iterator that yields no
   elements.
 * The [`matches`] and [`rmatches`] methods on `str` return iterators
   over substring matches.
-* [`Cell`] and [`RefCell`] both implement [`Eq`].
+* [`Cell`] and [`RefCell`] both implement `Eq`.
 * A number of methods for wrapping arithmetic are added to the
   integral types, [`wrapping_div`], [`wrapping_rem`],
   [`wrapping_neg`], [`wrapping_shl`], [`wrapping_shr`]. These are in
@@ -70,7 +79,7 @@ Libraries
   are used by code generators to emit implementations of [`Debug`].
 * `str` has new [`to_uppercase`][strup] and [`to_lowercase`][strlow]
   methods that convert case, following Unicode case mapping.
-* It is now easier to handle to poisoned locks. The [`PoisonError`]
+* It is now easier to handle poisoned locks. The [`PoisonError`]
   type, returned by failing lock operations, exposes `into_inner`,
   `get_ref`, and `get_mut`, which all give access to the inner lock
   guard, and allow the poisoned lock to continue to operate. The
@@ -144,6 +153,8 @@ Misc
 [dst]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 [parcodegen]: https://github.com/rust-lang/rust/pull/26018
 [packed]: https://github.com/rust-lang/rust/pull/25541
+[ad]: https://github.com/rust-lang/rust/pull/27382
+[win]: https://github.com/rust-lang/rust/pull/25350
 
 Version 1.1.0 (June 2015)
 =========================
diff --git a/configure b/configure
index 20143e631b8..2c8d78598b2 100755
--- a/configure
+++ b/configure
@@ -601,7 +601,9 @@ valopt llvm-root "" "set LLVM root"
 valopt python "" "set path to python"
 valopt jemalloc-root "" "set directory where libjemalloc_pic.a is located"
 valopt build "${DEFAULT_BUILD}" "GNUs ./configure syntax LLVM build triple"
-valopt android-cross-path "/opt/ndk_standalone" "Android NDK standalone path"
+valopt android-cross-path "/opt/ndk_standalone" "Android NDK standalone path (deprecated)"
+valopt arm-linux-androideabi-ndk "" "arm-linux-androideabi NDK standalone path"
+valopt aarch64-linux-android-ndk "" "aarch64-linux-android NDK standalone path"
 valopt release-channel "dev" "the name of the release channel to build"
 valopt musl-root "/usr/local" "MUSL root installation directory"
 
@@ -1003,11 +1005,9 @@ then
         (''|*clang)
         CFG_CLANG_REPORTED_VERSION=$($CFG_CC --version | grep version)
 
-        if [[ $CFG_CLANG_REPORTED_VERSION == *"(based on LLVM "* ]]
-        then
+        if echo $CFG_CLANG_REPORTED_VERSION | grep -q "(based on LLVM "; then
             CFG_CLANG_VERSION=$(echo $CFG_CLANG_REPORTED_VERSION | sed 's/.*(based on LLVM \(.*\))/\1/')
-        elif [[ $CFG_CLANG_REPORTED_VERSION == "Apple LLVM"* ]]
-        then
+        elif echo $CFG_CLANG_REPORTED_VERSION | grep -q "Apple LLVM"; then
             CFG_OSX_CLANG_VERSION=$(echo $CFG_CLANG_REPORTED_VERSION | sed 's/.*version \(.*\) .*/\1/')
         else
             CFG_CLANG_VERSION=$(echo $CFG_CLANG_REPORTED_VERSION | sed 's/.*version \(.*\) .*/\1/')
@@ -1112,20 +1112,24 @@ do
     fi
 
     case $i in
-        arm-linux-androideabi)
-
-            if [ ! -f $CFG_ANDROID_CROSS_PATH/bin/arm-linux-androideabi-gcc ]
-            then
-                err "NDK $CFG_ANDROID_CROSS_PATH/bin/arm-linux-androideabi-gcc not found"
-            fi
-            if [ ! -f $CFG_ANDROID_CROSS_PATH/bin/arm-linux-androideabi-g++ ]
+        *android*)
+            upper_snake_target=$(echo "$i" | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
+            eval ndk=\$"CFG_${upper_snake_target}_NDK"
+            if [ -z "$ndk" ]
             then
-                err "NDK $CFG_ANDROID_CROSS_PATH/bin/arm-linux-androideabi-g++ not found"
-            fi
-            if [ ! -f $CFG_ANDROID_CROSS_PATH/bin/arm-linux-androideabi-ar ]
-            then
-                err "NDK $CFG_ANDROID_CROSS_PATH/bin/arm-linux-androideabi-ar not found"
+                ndk=$CFG_ANDROID_CROSS_PATH
+                eval "CFG_${upper_snake_target}_NDK"=$CFG_ANDROID_CROSS_PATH
+                warn "generic/default Android NDK option is deprecated (use --$i-ndk option instead)"
             fi
+
+            # Perform a basic sanity check of the NDK
+            for android_ndk_tool in "$ndk/bin/$i-gcc" "$ndk/bin/$i-g++" "$ndk/bin/$i-ar"
+            do
+                if [ ! -f $android_ndk_tool ]
+                then
+                    err "NDK tool $android_ndk_tool not found (bad or missing --$i-ndk option?)"
+                fi
+            done
             ;;
 
         arm-apple-darwin)
@@ -1682,7 +1686,8 @@ putvar CFG_HOST
 putvar CFG_TARGET
 putvar CFG_LIBDIR_RELATIVE
 putvar CFG_DISABLE_MANAGE_SUBMODULES
-putvar CFG_ANDROID_CROSS_PATH
+putvar CFG_AARCH64_LINUX_ANDROID_NDK
+putvar CFG_ARM_LINUX_ANDROIDEABI_NDK
 putvar CFG_MANDIR
 
 # Avoid spurious warnings from clang by feeding it original source on
diff --git a/mk/cfg/aarch64-linux-android.mk b/mk/cfg/aarch64-linux-android.mk
index d7a1405c3d0..274f73834d4 100644
--- a/mk/cfg/aarch64-linux-android.mk
+++ b/mk/cfg/aarch64-linux-android.mk
@@ -1,9 +1,9 @@
 # aarch64-linux-android configuration
 # CROSS_PREFIX_aarch64-linux-android-
-CC_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc
-CXX_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-g++
-CPP_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc -E
-AR_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-ar
+CC_aarch64-linux-android=$(CFG_AARCH64_LINUX_ANDROID_NDK)/bin/aarch64-linux-android-gcc
+CXX_aarch64-linux-android=$(CFG_AARCH64_LINUX_ANDROID_NDK)/bin/aarch64-linux-android-g++
+CPP_aarch64-linux-android=$(CFG_AARCH64_LINUX_ANDROID_NDK)/bin/aarch64-linux-android-gcc -E
+AR_aarch64-linux-android=$(CFG_AARCH64_LINUX_ANDROID_NDK)/bin/aarch64-linux-android-ar
 CFG_LIB_NAME_aarch64-linux-android=lib$(1).so
 CFG_STATIC_LIB_NAME_aarch64-linux-android=lib$(1).a
 CFG_LIB_GLOB_aarch64-linux-android=lib$(1)-*.so
diff --git a/mk/cfg/arm-linux-androideabi.mk b/mk/cfg/arm-linux-androideabi.mk
index fdd38ba75fe..c084954f2e9 100644
--- a/mk/cfg/arm-linux-androideabi.mk
+++ b/mk/cfg/arm-linux-androideabi.mk
@@ -1,8 +1,8 @@
 # arm-linux-androideabi configuration
-CC_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
-CXX_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-g++
-CPP_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc -E
-AR_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-ar
+CC_arm-linux-androideabi=$(CFG_ARM_LINUX_ANDROIDEABI_NDK)/bin/arm-linux-androideabi-gcc
+CXX_arm-linux-androideabi=$(CFG_ARM_LINUX_ANDROIDEABI_NDK)/bin/arm-linux-androideabi-g++
+CPP_arm-linux-androideabi=$(CFG_ARM_LINUX_ANDROIDEABI_NDK)/bin/arm-linux-androideabi-gcc -E
+AR_arm-linux-androideabi=$(CFG_ARM_LINUX_ANDROIDEABI_NDK)/bin/arm-linux-androideabi-ar
 CFG_LIB_NAME_arm-linux-androideabi=lib$(1).so
 CFG_STATIC_LIB_NAME_arm-linux-androideabi=lib$(1).a
 CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
diff --git a/mk/ctags.mk b/mk/ctags.mk
index c7a3406a9e7..a116f2aba64 100644
--- a/mk/ctags.mk
+++ b/mk/ctags.mk
@@ -15,24 +15,11 @@
 
 .PHONY: TAGS.emacs TAGS.vi
 
-# This is using a blacklist approach, probably more durable than a whitelist.
-# We exclude: external dependencies (llvm, rt/{msvc,vg}),
-# tests (compiletest, test) and a couple of other things (rt/arch, etc)
-CTAGS_LOCATIONS=$(patsubst ${CFG_SRC_DIR}src/llvm,, \
-				$(patsubst ${CFG_SRC_DIR}src/compiletest,, \
-				$(patsubst ${CFG_SRC_DIR}src/test,, \
-				$(patsubst ${CFG_SRC_DIR}src/etc,, \
-				$(patsubst ${CFG_SRC_DIR}src/rt,, \
-				$(patsubst ${CFG_SRC_DIR}src/rt/arch,, \
-				$(patsubst ${CFG_SRC_DIR}src/rt/msvc,, \
-				$(patsubst ${CFG_SRC_DIR}src/rt/vg,, \
-				$(wildcard ${CFG_SRC_DIR}src/*) $(wildcard ${CFG_SRC_DIR}src/rt/*) \
-				))))))))
-CTAGS_OPTS=--options="${CFG_SRC_DIR}src/etc/ctags.rust" --languages=-javascript --recurse ${CTAGS_LOCATIONS}
-# We could use `--languages=Rust`, but there is value in producing tags for the
-# C++ parts of the code base too (at the time of writing, those are .h and .cpp
-# files in src/rt, src/rt/sync and src/rustllvm); we mainly just want to
-# exclude the external dependencies.
+CTAGS_LOCATIONS=$(wildcard ${CFG_SRC_DIR}src/lib*)
+CTAGS_LOCATIONS=$(patsubst ${CFG_SRC_DIR}src/librust%,, \
+                $(patsubst ${CFG_SRC_DIR}src/lib%test,, \
+				$(wildcard ${CFG_SRC_DIR}src/lib*))) ${CFG_SRC_DIR}src/libtest
+CTAGS_OPTS=--options="${CFG_SRC_DIR}src/etc/ctags.rust" --languages=Rust --recurse ${CTAGS_LOCATIONS}
 
 TAGS.emacs:
 	ctags -e -f $@ ${CTAGS_OPTS}
diff --git a/mk/docs.mk b/mk/docs.mk
index 617c3ddf8de..a8ab6d55d7f 100644
--- a/mk/docs.mk
+++ b/mk/docs.mk
@@ -77,7 +77,7 @@ ERR_IDX_GEN = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE)
 
 D := $(S)src/doc
 
-DOC_TARGETS := trpl style error-index
+DOC_TARGETS := trpl nomicon style error-index
 COMPILER_DOC_TARGETS :=
 DOC_L10N_TARGETS :=
 
@@ -287,6 +287,13 @@ doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/
 	$(Q)rm -rf doc/book
 	$(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book
 
+nomicon: doc/nomicon/index.html
+
+doc/nomicon/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/nomicon/*.md) | doc/
+	@$(call E, rustbook: $@)
+	$(Q)rm -rf doc/nomicon
+	$(Q)$(RUSTBOOK) build $(S)src/doc/nomicon doc/nomicon
+
 style: doc/style/index.html
 
 doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
diff --git a/mk/tests.mk b/mk/tests.mk
index 185cc9b2f4c..9341166beb0 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -162,7 +162,8 @@ $(foreach doc,$(DOCS), \
   $(eval $(call DOCTEST,md-$(doc),$(S)src/doc/$(doc).md)))
 $(foreach file,$(wildcard $(S)src/doc/trpl/*.md), \
   $(eval $(call DOCTEST,$(file:$(S)src/doc/trpl/%.md=trpl-%),$(file))))
-
+$(foreach file,$(wildcard $(S)src/doc/nomicon/*.md), \
+  $(eval $(call DOCTEST,$(file:$(S)src/doc/nomicon/%.md=nomicon-%),$(file))))
 ######################################################################
 # Main test targets
 ######################################################################
diff --git a/src/doc/nomicon/README.md b/src/doc/nomicon/README.md
new file mode 100644
index 00000000000..4554652a17a
--- /dev/null
+++ b/src/doc/nomicon/README.md
@@ -0,0 +1,38 @@
+% The Rustonomicon
+
+#### The Dark Arts of Advanced and Unsafe Rust Programming
+
+# NOTE: This is a draft document, and may contain serious errors
+
+> Instead of the programs I had hoped for, there came only a shuddering blackness
+and ineffable loneliness; and I saw at last a fearful truth which no one had
+ever dared to breathe before — the unwhisperable secret of secrets — The fact
+that this language of stone and stridor is not a sentient perpetuation of Rust
+as London is of Old London and Paris of Old Paris, but that it is in fact
+quite unsafe, its sprawling body imperfectly embalmed and infested with queer
+animate things which have nothing to do with it as it was in compilation.
+
+This book digs into all the awful details that are necessary to understand in
+order to write correct Unsafe Rust programs. Due to the nature of this problem,
+it may lead to unleashing untold horrors that shatter your psyche into a billion
+infinitesimal fragments of despair.
+
+Should you wish a long and happy career of writing Rust programs, you should
+turn back now and forget you ever saw this book. It is not necessary. However
+if you intend to write unsafe code -- or just want to dig into the guts of the
+language -- this book contains invaluable information.
+
+Unlike [The Book][trpl] we will be assuming considerable prior knowledge. In
+particular, you should be comfortable with basic systems programming and Rust.
+If you don't feel comfortable with these topics, you should consider [reading
+The Book][trpl] first. Though we will not be assuming that you have, and will
+take care to occasionally give a refresher on the basics where appropriate. You
+can skip straight to this book if you want; just know that we won't be
+explaining everything from the ground up.
+
+To be clear, this book goes into deep detail. We're going to dig into
+exception-safety, pointer aliasing, memory models, and even some type-theory.
+We will also be spending a lot of time talking about the different kinds
+of safety and guarantees.
+
+[trpl]: ../book/
diff --git a/src/doc/nomicon/SUMMARY.md b/src/doc/nomicon/SUMMARY.md
new file mode 100644
index 00000000000..7d4ef9c2514
--- /dev/null
+++ b/src/doc/nomicon/SUMMARY.md
@@ -0,0 +1,53 @@
+# Summary
+
+* [Meet Safe and Unsafe](meet-safe-and-unsafe.md)
+	* [How Safe and Unsafe Interact](safe-unsafe-meaning.md)
+	* [Working with Unsafe](working-with-unsafe.md)
+* [Data Layout](data.md)
+	* [repr(Rust)](repr-rust.md)
+	* [Exotically Sized Types](exotic-sizes.md)
+	* [Other reprs](other-reprs.md)
+* [Ownership](ownership.md)
+	* [References](references.md)
+	* [Lifetimes](lifetimes.md)
+	* [Limits of Lifetimes](lifetime-mismatch.md)
+	* [Lifetime Elision](lifetime-elision.md)
+	* [Unbounded Lifetimes](unbounded-lifetimes.md)
+	* [Higher-Rank Trait Bounds](hrtb.md)
+	* [Subtyping and Variance](subtyping.md)
+	* [Drop Check](dropck.md)
+	* [PhantomData](phantom-data.md)
+	* [Splitting Borrows](borrow-splitting.md)
+* [Type Conversions](conversions.md)
+	* [Coercions](coercions.md)
+	* [The Dot Operator](dot-operator.md)
+	* [Casts](casts.md)
+	* [Transmutes](transmutes.md)
+* [Uninitialized Memory](uninitialized.md)
+	* [Checked](checked-uninit.md)
+	* [Drop Flags](drop-flags.md)
+	* [Unchecked](unchecked-uninit.md)
+* [Ownership Based Resource Management](obrm.md)
+	* [Constructors](constructors.md)
+	* [Destructors](destructors.md)
+	* [Leaking](leaking.md)
+* [Unwinding](unwinding.md)
+	* [Exception Safety](exception-safety.md)
+	* [Poisoning](poisoning.md)
+* [Concurrency](concurrency.md)
+	* [Races](races.md)
+	* [Send and Sync](send-and-sync.md)
+	* [Atomics](atomics.md)
+* [Implementing Vec](vec.md)
+	* [Layout](vec-layout.md)
+	* [Allocating](vec-alloc.md)
+	* [Push and Pop](vec-push-pop.md)
+	* [Deallocating](vec-dealloc.md)
+	* [Deref](vec-deref.md)
+	* [Insert and Remove](vec-insert-remove.md)
+	* [IntoIter](vec-into-iter.md)
+	* [RawVec](vec-raw.md)
+	* [Drain](vec-drain.md)
+	* [Handling Zero-Sized Types](vec-zsts.md)
+	* [Final Code](vec-final.md)
+* [Implementing Arc and Mutex](arc-and-mutex.md)
diff --git a/src/doc/nomicon/arc-and-mutex.md b/src/doc/nomicon/arc-and-mutex.md
new file mode 100644
index 00000000000..fcafe55e409
--- /dev/null
+++ b/src/doc/nomicon/arc-and-mutex.md
@@ -0,0 +1,7 @@
+% Implementing Arc and Mutex
+
+Knowing the theory is all fine and good, but the *best* way to understand
+something is to use it. To better understand atomics and interior mutability,
+we'll be implementing versions of the standard library's Arc and Mutex types.
+
+TODO: ALL OF THIS OMG
diff --git a/src/doc/nomicon/atomics.md b/src/doc/nomicon/atomics.md
new file mode 100644
index 00000000000..2d567e39f8f
--- /dev/null
+++ b/src/doc/nomicon/atomics.md
@@ -0,0 +1,255 @@
+% Atomics
+
+Rust pretty blatantly just inherits C11's memory model for atomics. This is not
+due this model being particularly excellent or easy to understand. Indeed, this
+model is quite complex and known to have [several flaws][C11-busted]. Rather, it
+is a pragmatic concession to the fact that *everyone* is pretty bad at modeling
+atomics. At very least, we can benefit from existing tooling and research around
+C.
+
+Trying to fully explain the model in this book is fairly hopeless. It's defined
+in terms of madness-inducing causality graphs that require a full book to
+properly understand in a practical way. If you want all the nitty-gritty
+details, you should check out [C's specification (Section 7.17)][C11-model].
+Still, we'll try to cover the basics and some of the problems Rust developers
+face.
+
+The C11 memory model is fundamentally about trying to bridge the gap between the
+semantics we want, the optimizations compilers want, and the inconsistent chaos
+our hardware wants. *We* would like to just write programs and have them do
+exactly what we said but, you know, fast. Wouldn't that be great?
+
+
+
+
+# Compiler Reordering
+
+Compilers fundamentally want to be able to do all sorts of crazy transformations
+to reduce data dependencies and eliminate dead code. In particular, they may
+radically change the actual order of events, or make events never occur! If we
+write something like
+
+```rust,ignore
+x = 1;
+y = 3;
+x = 2;
+```
+
+The compiler may conclude that it would be best if your program did
+
+```rust,ignore
+x = 2;
+y = 3;
+```
+
+This has inverted the order of events and completely eliminated one event.
+From a single-threaded perspective this is completely unobservable: after all
+the statements have executed we are in exactly the same state. But if our
+program is multi-threaded, we may have been relying on `x` to actually be
+assigned to 1 before `y` was assigned. We would like the compiler to be
+able to make these kinds of optimizations, because they can seriously improve
+performance. On the other hand, we'd also like to be able to depend on our
+program *doing the thing we said*.
+
+
+
+
+# Hardware Reordering
+
+On the other hand, even if the compiler totally understood what we wanted and
+respected our wishes, our hardware might instead get us in trouble. Trouble
+comes from CPUs in the form of memory hierarchies. There is indeed a global
+shared memory space somewhere in your hardware, but from the perspective of each
+CPU core it is *so very far away* and *so very slow*. Each CPU would rather work
+with its local cache of the data and only go through all the anguish of
+talking to shared memory only when it doesn't actually have that memory in
+cache.
+
+After all, that's the whole point of the cache, right? If every read from the
+cache had to run back to shared memory to double check that it hadn't changed,
+what would the point be? The end result is that the hardware doesn't guarantee
+that events that occur in the same order on *one* thread, occur in the same
+order on *another* thread. To guarantee this, we must issue special instructions
+to the CPU telling it to be a bit less smart.
+
+For instance, say we convince the compiler to emit this logic:
+
+```text
+initial state: x = 0, y = 1
+
+THREAD 1        THREAD2
+y = 3;          if x == 1 {
+x = 1;              y *= 2;
+                }
+```
+
+Ideally this program has 2 possible final states:
+
+* `y = 3`: (thread 2 did the check before thread 1 completed)
+* `y = 6`: (thread 2 did the check after thread 1 completed)
+
+However there's a third potential state that the hardware enables:
+
+* `y = 2`: (thread 2 saw `x = 1`, but not `y = 3`, and then overwrote `y = 3`)
+
+It's worth noting that different kinds of CPU provide different guarantees. It
+is common to separate hardware into two categories: strongly-ordered and weakly-
+ordered. Most notably x86/64 provides strong ordering guarantees, while ARM
+provides weak ordering guarantees. This has two consequences for concurrent
+programming:
+
+* Asking for stronger guarantees on strongly-ordered hardware may be cheap or
+  even free because they already provide strong guarantees unconditionally.
+  Weaker guarantees may only yield performance wins on weakly-ordered hardware.
+
+* Asking for guarantees that are too weak on strongly-ordered hardware is
+  more likely to *happen* to work, even though your program is strictly
+  incorrect. If possible, concurrent algorithms should be tested on
+  weakly-ordered hardware.
+
+
+
+
+
+# Data Accesses
+
+The C11 memory model attempts to bridge the gap by allowing us to talk about the
+*causality* of our program. Generally, this is by establishing a *happens
+before* relationship between parts of the program and the threads that are
+running them. This gives the hardware and compiler room to optimize the program
+more aggressively where a strict happens-before relationship isn't established,
+but forces them to be more careful where one is established. The way we
+communicate these relationships are through *data accesses* and *atomic
+accesses*.
+
+Data accesses are the bread-and-butter of the programming world. They are
+fundamentally unsynchronized and compilers are free to aggressively optimize
+them. In particular, data accesses are free to be reordered by the compiler on
+the assumption that the program is single-threaded. The hardware is also free to
+propagate the changes made in data accesses to other threads as lazily and
+inconsistently as it wants. Mostly critically, data accesses are how data races
+happen. Data accesses are very friendly to the hardware and compiler, but as
+we've seen they offer *awful* semantics to try to write synchronized code with.
+Actually, that's too weak.
+
+**It is literally impossible to write correct synchronized code using only data
+accesses.**
+
+Atomic accesses are how we tell the hardware and compiler that our program is
+multi-threaded. Each atomic access can be marked with an *ordering* that
+specifies what kind of relationship it establishes with other accesses. In
+practice, this boils down to telling the compiler and hardware certain things
+they *can't* do. For the compiler, this largely revolves around re-ordering of
+instructions. For the hardware, this largely revolves around how writes are
+propagated to other threads. The set of orderings Rust exposes are:
+
+* Sequentially Consistent (SeqCst)
+* Release
+* Acquire
+* Relaxed
+
+(Note: We explicitly do not expose the C11 *consume* ordering)
+
+TODO: negative reasoning vs positive reasoning? TODO: "can't forget to
+synchronize"
+
+
+
+# Sequentially Consistent
+
+Sequentially Consistent is the most powerful of all, implying the restrictions
+of all other orderings. Intuitively, a sequentially consistent operation
+cannot be reordered: all accesses on one thread that happen before and after a
+SeqCst access stay before and after it. A data-race-free program that uses
+only sequentially consistent atomics and data accesses has the very nice
+property that there is a single global execution of the program's instructions
+that all threads agree on. This execution is also particularly nice to reason
+about: it's just an interleaving of each thread's individual executions. This
+does not hold if you start using the weaker atomic orderings.
+
+The relative developer-friendliness of sequential consistency doesn't come for
+free. Even on strongly-ordered platforms sequential consistency involves
+emitting memory fences.
+
+In practice, sequential consistency is rarely necessary for program correctness.
+However sequential consistency is definitely the right choice if you're not
+confident about the other memory orders. Having your program run a bit slower
+than it needs to is certainly better than it running incorrectly! It's also
+mechanically trivial to downgrade atomic operations to have a weaker
+consistency later on. Just change `SeqCst` to `Relaxed` and you're done! Of
+course, proving that this transformation is *correct* is a whole other matter.
+
+
+
+
+# Acquire-Release
+
+Acquire and Release are largely intended to be paired. Their names hint at their
+use case: they're perfectly suited for acquiring and releasing locks, and
+ensuring that critical sections don't overlap.
+
+Intuitively, an acquire access ensures that every access after it stays after
+it. However operations that occur before an acquire are free to be reordered to
+occur after it. Similarly, a release access ensures that every access before it
+stays before it. However operations that occur after a release are free to be
+reordered to occur before it.
+
+When thread A releases a location in memory and then thread B subsequently
+acquires *the same* location in memory, causality is established. Every write
+that happened before A's release will be observed by B after its release.
+However no causality is established with any other threads. Similarly, no
+causality is established if A and B access *different* locations in memory.
+
+Basic use of release-acquire is therefore simple: you acquire a location of
+memory to begin the critical section, and then release that location to end it.
+For instance, a simple spinlock might look like:
+
+```rust
+use std::sync::Arc;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::thread;
+
+fn main() {
+    let lock = Arc::new(AtomicBool::new(true)); // value answers "am I locked?"
+
+    // ... distribute lock to threads somehow ...
+
+    // Try to acquire the lock by setting it to false
+    while !lock.compare_and_swap(true, false, Ordering::Acquire) { }
+    // broke out of the loop, so we successfully acquired the lock!
+
+    // ... scary data accesses ...
+
+    // ok we're done, release the lock
+    lock.store(true, Ordering::Release);
+}
+```
+
+On strongly-ordered platforms most accesses have release or acquire semantics,
+making release and acquire often totally free. This is not the case on
+weakly-ordered platforms.
+
+
+
+
+# Relaxed
+
+Relaxed accesses are the absolute weakest. They can be freely re-ordered and
+provide no happens-before relationship. Still, relaxed operations are still
+atomic. That is, they don't count as data accesses and any read-modify-write
+operations done to them occur atomically. Relaxed operations are appropriate for
+things that you definitely want to happen, but don't particularly otherwise care
+about. For instance, incrementing a counter can be safely done by multiple
+threads using a relaxed `fetch_add` if you're not using the counter to
+synchronize any other accesses.
+
+There's rarely a benefit in making an operation relaxed on strongly-ordered
+platforms, since they usually provide release-acquire semantics anyway. However
+relaxed operations can be cheaper on weakly-ordered platforms.
+
+
+
+
+
+[C11-busted]: http://plv.mpi-sws.org/c11comp/popl15.pdf
+[C11-model]: http://www.open-std.org/jtc1/sc22/wg14/www/standards.html#9899
diff --git a/src/doc/nomicon/borrow-splitting.md b/src/doc/nomicon/borrow-splitting.md
new file mode 100644
index 00000000000..cc5bc8a602d
--- /dev/null
+++ b/src/doc/nomicon/borrow-splitting.md
@@ -0,0 +1,291 @@
+% Splitting Borrows
+
+The mutual exclusion property of mutable references can be very limiting when
+working with a composite structure. The borrow checker understands some basic
+stuff, but will fall over pretty easily. It does understand structs
+sufficiently to know that it's possible to borrow disjoint fields of a struct
+simultaneously. So this works today:
+
+```rust
+struct Foo {
+    a: i32,
+    b: i32,
+    c: i32,
+}
+
+let mut x = Foo {a: 0, b: 0, c: 0};
+let a = &mut x.a;
+let b = &mut x.b;
+let c = &x.c;
+*b += 1;
+let c2 = &x.c;
+*a += 10;
+println!("{} {} {} {}", a, b, c, c2);
+```
+
+However borrowck doesn't understand arrays or slices in any way, so this doesn't
+work:
+
+```rust,ignore
+let mut x = [1, 2, 3];
+let a = &mut x[0];
+let b = &mut x[1];
+println!("{} {}", a, b);
+```
+
+```text
+<anon>:4:14: 4:18 error: cannot borrow `x[..]` as mutable more than once at a time
+<anon>:4 let b = &mut x[1];
+                      ^~~~
+<anon>:3:14: 3:18 note: previous borrow of `x[..]` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x[..]` until the borrow ends
+<anon>:3 let a = &mut x[0];
+                      ^~~~
+<anon>:6:2: 6:2 note: previous borrow ends here
+<anon>:1 fn main() {
+<anon>:2 let mut x = [1, 2, 3];
+<anon>:3 let a = &mut x[0];
+<anon>:4 let b = &mut x[1];
+<anon>:5 println!("{} {}", a, b);
+<anon>:6 }
+         ^
+error: aborting due to 2 previous errors
+```
+
+While it was plausible that borrowck could understand this simple case, it's
+pretty clearly hopeless for borrowck to understand disjointness in general
+container types like a tree, especially if distinct keys actually *do* map
+to the same value.
+
+In order to "teach" borrowck that what we're doing is ok, we need to drop down
+to unsafe code. For instance, mutable slices expose a `split_at_mut` function
+that consumes the slice and returns two mutable slices. One for everything to
+the left of the index, and one for everything to the right. Intuitively we know
+this is safe because the slices don't overlap, and therefore alias. However
+the implementation requires some unsafety:
+
+```rust,ignore
+fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+    let len = self.len();
+    let ptr = self.as_mut_ptr();
+    assert!(mid <= len);
+    unsafe {
+        (from_raw_parts_mut(ptr, mid),
+         from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
+    }
+}
+```
+
+This is actually a bit subtle. So as to avoid ever making two `&mut`'s to the
+same value, we explicitly construct brand-new slices through raw pointers.
+
+However more subtle is how iterators that yield mutable references work.
+The iterator trait is defined as follows:
+
+```rust
+trait Iterator {
+    type Item;
+
+    fn next(&mut self) -> Option<Self::Item>;
+}
+```
+
+Given this definition, Self::Item has *no* connection to `self`. This means that
+we can call `next` several times in a row, and hold onto all the results
+*concurrently*. This is perfectly fine for by-value iterators, which have
+exactly these semantics. It's also actually fine for shared references, as they
+admit arbitrarily many references to the same thing (although the iterator needs
+to be a separate object from the thing being shared).
+
+But mutable references make this a mess. At first glance, they might seem
+completely incompatible with this API, as it would produce multiple mutable
+references to the same object!
+
+However it actually *does* work, exactly because iterators are one-shot objects.
+Everything an IterMut yields will be yielded at most once, so we don't
+actually ever yield multiple mutable references to the same piece of data.
+
+Perhaps surprisingly, mutable iterators don't require unsafe code to be
+implemented for many types!
+
+For instance here's a singly linked list:
+
+```rust
+# fn main() {}
+type Link<T> = Option<Box<Node<T>>>;
+
+struct Node<T> {
+    elem: T,
+    next: Link<T>,
+}
+
+pub struct LinkedList<T> {
+    head: Link<T>,
+}
+
+pub struct IterMut<'a, T: 'a>(Option<&'a mut Node<T>>);
+
+impl<T> LinkedList<T> {
+    fn iter_mut(&mut self) -> IterMut<T> {
+        IterMut(self.head.as_mut().map(|node| &mut **node))
+    }
+}
+
+impl<'a, T> Iterator for IterMut<'a, T> {
+    type Item = &'a mut T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.0.take().map(|node| {
+            self.0 = node.next.as_mut().map(|node| &mut **node);
+            &mut node.elem
+        })
+    }
+}
+```
+
+Here's a mutable slice:
+
+```rust
+# fn main() {}
+use std::mem;
+
+pub struct IterMut<'a, T: 'a>(&'a mut[T]);
+
+impl<'a, T> Iterator for IterMut<'a, T> {
+    type Item = &'a mut T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let slice = mem::replace(&mut self.0, &mut []);
+        if slice.is_empty() { return None; }
+
+        let (l, r) = slice.split_at_mut(1);
+        self.0 = r;
+        l.get_mut(0)
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        let slice = mem::replace(&mut self.0, &mut []);
+        if slice.is_empty() { return None; }
+
+        let new_len = slice.len() - 1;
+        let (l, r) = slice.split_at_mut(new_len);
+        self.0 = l;
+        r.get_mut(0)
+    }
+}
+```
+
+And here's a binary tree:
+
+```rust
+# fn main() {}
+use std::collections::VecDeque;
+
+type Link<T> = Option<Box<Node<T>>>;
+
+struct Node<T> {
+    elem: T,
+    left: Link<T>,
+    right: Link<T>,
+}
+
+pub struct Tree<T> {
+    root: Link<T>,
+}
+
+struct NodeIterMut<'a, T: 'a> {
+    elem: Option<&'a mut T>,
+    left: Option<&'a mut Node<T>>,
+    right: Option<&'a mut Node<T>>,
+}
+
+enum State<'a, T: 'a> {
+    Elem(&'a mut T),
+    Node(&'a mut Node<T>),
+}
+
+pub struct IterMut<'a, T: 'a>(VecDeque<NodeIterMut<'a, T>>);
+
+impl<T> Tree<T> {
+    pub fn iter_mut(&mut self) -> IterMut<T> {
+        let mut deque = VecDeque::new();
+        self.root.as_mut().map(|root| deque.push_front(root.iter_mut()));
+        IterMut(deque)
+    }
+}
+
+impl<T> Node<T> {
+    pub fn iter_mut(&mut self) -> NodeIterMut<T> {
+        NodeIterMut {
+            elem: Some(&mut self.elem),
+            left: self.left.as_mut().map(|node| &mut **node),
+            right: self.right.as_mut().map(|node| &mut **node),
+        }
+    }
+}
+
+
+impl<'a, T> Iterator for NodeIterMut<'a, T> {
+    type Item = State<'a, T>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match self.left.take() {
+            Some(node) => Some(State::Node(node)),
+            None => match self.elem.take() {
+                Some(elem) => Some(State::Elem(elem)),
+                None => match self.right.take() {
+                    Some(node) => Some(State::Node(node)),
+                    None => None,
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for NodeIterMut<'a, T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        match self.right.take() {
+            Some(node) => Some(State::Node(node)),
+            None => match self.elem.take() {
+                Some(elem) => Some(State::Elem(elem)),
+                None => match self.left.take() {
+                    Some(node) => Some(State::Node(node)),
+                    None => None,
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T> Iterator for IterMut<'a, T> {
+    type Item = &'a mut T;
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.0.front_mut().and_then(|node_it| node_it.next()) {
+                Some(State::Elem(elem)) => return Some(elem),
+                Some(State::Node(node)) => self.0.push_front(node.iter_mut()),
+                None => if let None = self.0.pop_front() { return None },
+            }
+        }
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.0.back_mut().and_then(|node_it| node_it.next_back()) {
+                Some(State::Elem(elem)) => return Some(elem),
+                Some(State::Node(node)) => self.0.push_back(node.iter_mut()),
+                None => if let None = self.0.pop_back() { return None },
+            }
+        }
+    }
+}
+```
+
+All of these are completely safe and work on stable Rust! This ultimately
+falls out of the simple struct case we saw before: Rust understands that you
+can safely split a mutable reference into subfields. We can then encode
+permanently consuming a reference via Options (or in the case of slices,
+replacing with an empty slice).
diff --git a/src/doc/nomicon/casts.md b/src/doc/nomicon/casts.md
new file mode 100644
index 00000000000..5f07709cf45
--- /dev/null
+++ b/src/doc/nomicon/casts.md
@@ -0,0 +1,71 @@
+% Casts
+
+Casts are a superset of coercions: every coercion can be explicitly
+invoked via a cast. However some conversions require a cast.
+While coercions are pervasive and largely harmless, these "true casts"
+are rare and potentially dangerous. As such, casts must be explicitly invoked
+using the `as` keyword: `expr as Type`.
+
+True casts generally revolve around raw pointers and the primitive numeric
+types. Even though they're dangerous, these casts are infallible at runtime.
+If a cast triggers some subtle corner case no indication will be given that
+this occurred. The cast will simply succeed. That said, casts must be valid
+at the type level, or else they will be prevented statically. For instance,
+`7u8 as bool` will not compile.
+
+That said, casts aren't `unsafe` because they generally can't violate memory
+safety *on their own*. For instance, converting an integer to a raw pointer can
+very easily lead to terrible things. However the act of creating the pointer
+itself is safe, because actually using a raw pointer is already marked as
+`unsafe`.
+
+Here's an exhaustive list of all the true casts. For brevity, we will use `*`
+to denote either a `*const` or `*mut`, and `integer` to denote any integral
+primitive:
+
+ * `*T as *U` where `T, U: Sized`
+ * `*T as *U` TODO: explain unsized situation
+ * `*T as integer`
+ * `integer as *T`
+ * `number as number`
+ * `C-like-enum as integer`
+ * `bool as integer`
+ * `char as integer`
+ * `u8 as char`
+ * `&[T; n] as *const T`
+ * `fn as *T` where `T: Sized`
+ * `fn as integer`
+
+Note that lengths are not adjusted when casting raw slices -
+`*const [u16] as *const [u8]` creates a slice that only includes
+half of the original memory.
+
+Casting is not transitive, that is, even if `e as U1 as U2` is a valid
+expression, `e as U2` is not necessarily so.
+
+For numeric casts, there are quite a few cases to consider:
+
+* casting between two integers of the same size (e.g. i32 -> u32) is a no-op
+* casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
+  truncate
+* casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
+    * zero-extend if the source is unsigned
+    * sign-extend if the source is signed
+* casting from a float to an integer will round the float towards zero
+    * **[NOTE: currently this will cause Undefined Behaviour if the rounded
+      value cannot be represented by the target integer type][float-int]**.
+      This includes Inf and NaN. This is a bug and will be fixed.
+* casting from an integer to float will produce the floating point
+  representation of the integer, rounded if necessary (rounding strategy
+  unspecified)
+* casting from an f32 to an f64 is perfect and lossless
+* casting from an f64 to an f32 will produce the closest possible value
+  (rounding strategy unspecified)
+    * **[NOTE: currently this will cause Undefined Behaviour if the value
+      is finite but larger or smaller than the largest or smallest finite
+      value representable by f32][float-float]**. This is a bug and will
+      be fixed.
+
+
+[float-int]: https://github.com/rust-lang/rust/issues/10184
+[float-float]: https://github.com/rust-lang/rust/issues/15536
diff --git a/src/doc/nomicon/checked-uninit.md b/src/doc/nomicon/checked-uninit.md
new file mode 100644
index 00000000000..f7c4482a4ab
--- /dev/null
+++ b/src/doc/nomicon/checked-uninit.md
@@ -0,0 +1,117 @@
+% Checked Uninitialized Memory
+
+Like C, all stack variables in Rust are uninitialized until a value is
+explicitly assigned to them. Unlike C, Rust statically prevents you from ever
+reading them until you do:
+
+```rust,ignore
+fn main() {
+    let x: i32;
+    println!("{}", x);
+}
+```
+
+```text
+src/main.rs:3:20: 3:21 error: use of possibly uninitialized variable: `x`
+src/main.rs:3     println!("{}", x);
+                                 ^
+```
+
+This is based off of a basic branch analysis: every branch must assign a value
+to `x` before it is first used. Interestingly, Rust doesn't require the variable
+to be mutable to perform a delayed initialization if every branch assigns
+exactly once. However the analysis does not take advantage of constant analysis
+or anything like that. So this compiles:
+
+```rust
+fn main() {
+    let x: i32;
+
+    if true {
+        x = 1;
+    } else {
+        x = 2;
+    }
+
+    println!("{}", x);
+}
+```
+
+but this doesn't:
+
+```rust,ignore
+fn main() {
+    let x: i32;
+    if true {
+        x = 1;
+    }
+    println!("{}", x);
+}
+```
+
+```text
+src/main.rs:6:17: 6:18 error: use of possibly uninitialized variable: `x`
+src/main.rs:6   println!("{}", x);
+```
+
+while this does:
+
+```rust
+fn main() {
+    let x: i32;
+    if true {
+        x = 1;
+        println!("{}", x);
+    }
+    // Don't care that there are branches where it's not initialized
+    // since we don't use the value in those branches
+}
+```
+
+Of course, while the analysis doesn't consider actual values, it does
+have a relatively sophisticated understanding of dependencies and control
+flow. For instance, this works:
+
+```rust
+let x: i32;
+
+loop {
+    // Rust doesn't understand that this branch will be taken unconditionally,
+    // because it relies on actual values.
+    if true {
+        // But it does understand that it will only be taken once because
+        // we unconditionally break out of it. Therefore `x` doesn't
+        // need to be marked as mutable.
+        x = 0;
+        break;
+    }
+}
+// It also knows that it's impossible to get here without reaching the break.
+// And therefore that `x` must be initialized here!
+println!("{}", x);
+```
+
+If a value is moved out of a variable, that variable becomes logically
+uninitialized if the type of the value isn't Copy. That is:
+
+```rust
+fn main() {
+    let x = 0;
+    let y = Box::new(0);
+    let z1 = x; // x is still valid because i32 is Copy
+    let z2 = y; // y is now logically uninitialized because Box isn't Copy
+}
+```
+
+However reassigning `y` in this example *would* require `y` to be marked as
+mutable, as a Safe Rust program could observe that the value of `y` changed:
+
+```rust
+fn main() {
+    let mut y = Box::new(0);
+    let z = y; // y is now logically uninitialized because Box isn't Copy
+    y = Box::new(1); // reinitialize y
+}
+```
+
+Otherwise it's like `y` is a brand new variable.
diff --git a/src/doc/nomicon/coercions.md b/src/doc/nomicon/coercions.md
new file mode 100644
index 00000000000..2e33a6729d1
--- /dev/null
+++ b/src/doc/nomicon/coercions.md
@@ -0,0 +1,70 @@
+% Coercions
+
+Types can implicitly be coerced to change in certain contexts. These changes are
+generally just *weakening* of types, largely focused around pointers and
+lifetimes. They mostly exist to make Rust "just work" in more cases, and are
+largely harmless.
+
+Here's all the kinds of coercion:
+
+Coercion is allowed between the following types:
+
+* Transitivity: `T_1` to `T_3` where `T_1` coerces to `T_2` and `T_2` coerces to
+  `T_3`
+* Pointer Weakening:
+    * `&mut T` to `&T`
+    * `*mut T` to `*const T`
+    * `&T` to `*const T`
+    * `&mut T` to `*mut T`
+* Unsizing: `T` to `U` if `T` implements `CoerceUnsized<U>`
+
+`CoerceUnsized<Pointer<U>> for Pointer<T> where T: Unsize<U>` is implemented
+for all pointer types (including smart pointers like Box and Rc). Unsize is
+only implemented automatically, and enables the following transformations:
+
+* `[T, ..n]` => `[T]`
+* `T` => `Trait` where `T: Trait`
+* `Foo<..., T, ...>` => `Foo<..., U, ...>` where:
+    * `T: Unsize<U>`
+    * `Foo` is a struct
+    * Only the last field of `Foo` has type `T`
+    * `T` is not part of the type of any other fields
+
+Coercions occur at a *coercion site*. Any location that is explicitly typed
+will cause a coercion to its type. If inference is necessary, the coercion will
+not be performed. Exhaustively, the coercion sites for an expression `e` to
+type `U` are:
+
+* let statements, statics, and consts: `let x: U = e`
+* Arguments to functions: `takes_a_U(e)`
+* Any expression that will be returned: `fn foo() -> U { e }`
+* Struct literals: `Foo { some_u: e }`
+* Array literals: `let x: [U; 10] = [e, ..]`
+* Tuple literals: `let x: (U, ..) = (e, ..)`
+* The last expression in a block: `let x: U = { ..; e }`
+
+Note that we do not perform coercions when matching traits (except for
+receivers, see below). If there is an impl for some type `U` and `T` coerces to
+`U`, that does not constitute an implementation for `T`. For example, the
+following will not type check, even though it is OK to coerce `t` to `&T` and
+there is an impl for `&T`:
+
+```rust,ignore
+trait Trait {}
+
+fn foo<X: Trait>(t: X) {}
+
+impl<'a> Trait for &'a i32 {}
+
+
+fn main() {
+    let t: &mut i32 = &mut 0;
+    foo(t);
+}
+```
+
+```text
+<anon>:10:5: 10:8 error: the trait `Trait` is not implemented for the type `&mut i32` [E0277]
+<anon>:10     foo(t);
+              ^~~
+```
diff --git a/src/doc/nomicon/concurrency.md b/src/doc/nomicon/concurrency.md
new file mode 100644
index 00000000000..9dcbecdd5b3
--- /dev/null
+++ b/src/doc/nomicon/concurrency.md
@@ -0,0 +1,13 @@
+% Concurrency and Paralellism
+
+Rust as a language doesn't *really* have an opinion on how to do concurrency or
+parallelism. The standard library exposes OS threads and blocking sys-calls
+because everyone has those, and they're uniform enough that you can provide
+an abstraction over them in a relatively uncontroversial way. Message passing,
+green threads, and async APIs are all diverse enough that any abstraction over
+them tends to involve trade-offs that we weren't willing to commit to for 1.0.
+
+However the way Rust models concurrency makes it relatively easy design your own
+concurrency paradigm as a library and have everyone else's code Just Work
+with yours. Just require the right lifetimes and Send and Sync where appropriate
+and you're off to the races. Or rather, off to the... not... having... races.
diff --git a/src/doc/nomicon/constructors.md b/src/doc/nomicon/constructors.md
new file mode 100644
index 00000000000..97817cd1f90
--- /dev/null
+++ b/src/doc/nomicon/constructors.md
@@ -0,0 +1,59 @@
+% Constructors
+
+There is exactly one way to create an instance of a user-defined type: name it,
+and initialize all its fields at once:
+
+```rust
+struct Foo {
+    a: u8,
+    b: u32,
+    c: bool,
+}
+
+enum Bar {
+    X(u32),
+    Y(bool),
+}
+
+struct Unit;
+
+let foo = Foo { a: 0, b: 1, c: false };
+let bar = Bar::X(0);
+let empty = Unit;
+```
+
+That's it. Every other way you make an instance of a type is just calling a
+totally vanilla function that does some stuff and eventually bottoms out to The
+One True Constructor.
+
+Unlike C++, Rust does not come with a slew of built-in kinds of constructor.
+There are no Copy, Default, Assignment, Move, or whatever constructors. The
+reasons for this are varied, but it largely boils down to Rust's philosophy of
+*being explicit*.
+
+Move constructors are meaningless in Rust because we don't enable types to
+"care" about their location in memory. Every type must be ready for it to be
+blindly memcopied to somewhere else in memory. This means pure on-the-stack-but-
+still-movable intrusive linked lists are simply not happening in Rust (safely).
+
+Assignment and copy constructors similarly don't exist because move semantics
+are the only semantics in Rust. At most `x = y` just moves the bits of y into
+the x variable. Rust does provide two facilities for providing C++'s copy-
+oriented semantics: `Copy` and `Clone`. Clone is our moral equivalent of a copy
+constructor, but it's never implicitly invoked. You have to explicitly call
+`clone` on an element you want to be cloned. Copy is a special case of Clone
+where the implementation is just "copy the bits". Copy types *are* implicitly
+cloned whenever they're moved, but because of the definition of Copy this just
+means not treating the old copy as uninitialized -- a no-op.
+
+While Rust provides a `Default` trait for specifying the moral equivalent of a
+default constructor, it's incredibly rare for this trait to be used. This is
+because variables [aren't implicitly initialized][uninit]. Default is basically
+only useful for generic programming. In concrete contexts, a type will provide a
+static `new` method for any kind of "default" constructor. This has no relation
+to `new` in other languages and has no special meaning. It's just a naming
+convention.
+
+TODO: talk about "placement new"?
+
+[uninit]: uninitialized.html
diff --git a/src/doc/nomicon/conversions.md b/src/doc/nomicon/conversions.md
new file mode 100644
index 00000000000..b099a789ec3
--- /dev/null
+++ b/src/doc/nomicon/conversions.md
@@ -0,0 +1,34 @@
+% Type Conversions
+
+At the end of the day, everything is just a pile of bits somewhere, and type
+systems are just there to help us use those bits right. There are two common
+problems with typing bits: needing to reinterpret those exact bits as a
+different type, and needing to change the bits to have equivalent meaning for
+a different type. Because Rust encourages encoding important properties in the
+type system, these problems are incredibly pervasive. As such, Rust
+consequently gives you several ways to solve them.
+
+First we'll look at the ways that Safe Rust gives you to reinterpret values.
+The most trivial way to do this is to just destructure a value into its
+constituent parts and then build a new type out of them. e.g.
+
+```rust
+struct Foo {
+    x: u32,
+    y: u16,
+}
+
+struct Bar {
+    a: u32,
+    b: u16,
+}
+
+fn reinterpret(foo: Foo) -> Bar {
+    let Foo { x, y } = foo;
+    Bar { a: x, b: y }
+}
+```
+
+But this is, at best, annoying. For common conversions, Rust provides
+more ergonomic alternatives.
+
diff --git a/src/doc/nomicon/data.md b/src/doc/nomicon/data.md
new file mode 100644
index 00000000000..d0a796b7f0b
--- /dev/null
+++ b/src/doc/nomicon/data.md
@@ -0,0 +1,5 @@
+% Data Representation in Rust
+
+Low-level programming cares a lot about data layout. It's a big deal. It also
+pervasively influences the rest of the language, so we're going to start by
+digging into how data is represented in Rust.
diff --git a/src/doc/nomicon/destructors.md b/src/doc/nomicon/destructors.md
new file mode 100644
index 00000000000..568f7c07f59
--- /dev/null
+++ b/src/doc/nomicon/destructors.md
@@ -0,0 +1,181 @@
+% Destructors
+
+What the language *does* provide is full-blown automatic destructors through the
+`Drop` trait, which provides the following method:
+
+```rust,ignore
+fn drop(&mut self);
+```
+
+This method gives the type time to somehow finish what it was doing.
+
+**After `drop` is run, Rust will recursively try to drop all of the fields
+of `self`.**
+
+This is a convenience feature so that you don't have to write "destructor
+boilerplate" to drop children. If a struct has no special logic for being
+dropped other than dropping its children, then it means `Drop` doesn't need to
+be implemented at all!
+
+**There is no stable way to prevent this behaviour in Rust 1.0.**
+
+Note that taking `&mut self` means that even if you could suppress recursive
+Drop, Rust will prevent you from e.g. moving fields out of self. For most types,
+this is totally fine.
+
+For instance, a custom implementation of `Box` might write `Drop` like this:
+
+```rust
+#![feature(heap_api, core_intrinsics, unique)]
+
+use std::rt::heap;
+use std::ptr::Unique;
+use std::intrinsics::drop_in_place;
+use std::mem;
+
+struct Box<T>{ ptr: Unique<T> }
+
+impl<T> Drop for Box<T> {
+    fn drop(&mut self) {
+        unsafe {
+            drop_in_place(*self.ptr);
+            heap::deallocate((*self.ptr) as *mut u8,
+                             mem::size_of::<T>(),
+                             mem::align_of::<T>());
+        }
+    }
+}
+```
+
+and this works fine because when Rust goes to drop the `ptr` field it just sees
+a [Unique][] that has no actual `Drop` implementation. Similarly nothing can
+use-after-free the `ptr` because when drop exits, it becomes inacessible.
+
+However this wouldn't work:
+
+```rust
+#![feature(heap_api, core_intrinsics, unique)]
+
+use std::rt::heap;
+use std::ptr::Unique;
+use std::intrinsics::drop_in_place;
+use std::mem;
+
+struct Box<T>{ ptr: Unique<T> }
+
+impl<T> Drop for Box<T> {
+    fn drop(&mut self) {
+        unsafe {
+            drop_in_place(*self.ptr);
+            heap::deallocate((*self.ptr) as *mut u8,
+                             mem::size_of::<T>(),
+                             mem::align_of::<T>());
+        }
+    }
+}
+
+struct SuperBox<T> { my_box: Box<T> }
+
+impl<T> Drop for SuperBox<T> {
+    fn drop(&mut self) {
+        unsafe {
+            // Hyper-optimized: deallocate the box's contents for it
+            // without `drop`ing the contents
+            heap::deallocate((*self.my_box.ptr) as *mut u8,
+                             mem::size_of::<T>(),
+                             mem::align_of::<T>());
+        }
+    }
+}
+```
+
+After we deallocate the `box`'s ptr in SuperBox's destructor, Rust will
+happily proceed to tell the box to Drop itself and everything will blow up with
+use-after-frees and double-frees.
+
+Note that the recursive drop behaviour applies to all structs and enums
+regardless of whether they implement Drop. Therefore something like
+
+```rust
+struct Boxy<T> {
+    data1: Box<T>,
+    data2: Box<T>,
+    info: u32,
+}
+```
+
+will have its data1 and data2's fields destructors whenever it "would" be
+dropped, even though it itself doesn't implement Drop. We say that such a type
+*needs Drop*, even though it is not itself Drop.
+
+Similarly,
+
+```rust
+enum Link {
+    Next(Box<Link>),
+    None,
+}
+```
+
+will have its inner Box field dropped if and only if an instance stores the
+Next variant.
+
+In general this works really nice because you don't need to worry about
+adding/removing drops when you refactor your data layout. Still there's
+certainly many valid usecases for needing to do trickier things with
+destructors.
+
+The classic safe solution to overriding recursive drop and allowing moving out
+of Self during `drop` is to use an Option:
+
+```rust
+#![feature(heap_api, core_intrinsics, unique)]
+
+use std::rt::heap;
+use std::ptr::Unique;
+use std::intrinsics::drop_in_place;
+use std::mem;
+
+struct Box<T>{ ptr: Unique<T> }
+
+impl<T> Drop for Box<T> {
+    fn drop(&mut self) {
+        unsafe {
+            drop_in_place(*self.ptr);
+            heap::deallocate((*self.ptr) as *mut u8,
+                             mem::size_of::<T>(),
+                             mem::align_of::<T>());
+        }
+    }
+}
+
+struct SuperBox<T> { my_box: Option<Box<T>> }
+
+impl<T> Drop for SuperBox<T> {
+    fn drop(&mut self) {
+        unsafe {
+            // Hyper-optimized: deallocate the box's contents for it
+            // without `drop`ing the contents. Need to set the `box`
+            // field as `None` to prevent Rust from trying to Drop it.
+            let my_box = self.my_box.take().unwrap();
+            heap::deallocate((*my_box.ptr) as *mut u8,
+                             mem::size_of::<T>(),
+                             mem::align_of::<T>());
+            mem::forget(my_box);
+        }
+    }
+}
+```
+
+However this has fairly odd semantics: you're saying that a field that *should*
+always be Some *may* be None, just because that happens in the destructor. Of
+course this conversely makes a lot of sense: you can call arbitrary methods on
+self during the destructor, and this should prevent you from ever doing so after
+deinitializing the field. Not that it will prevent you from producing any other
+arbitrarily invalid state in there.
+
+On balance this is an ok choice. Certainly what you should reach for by default.
+However, in the future we expect there to be a first-class way to announce that
+a field shouldn't be automatically dropped.
+
+[Unique]: phantom-data.html
diff --git a/src/doc/nomicon/dot-operator.md b/src/doc/nomicon/dot-operator.md
new file mode 100644
index 00000000000..5d2010d15a8
--- /dev/null
+++ b/src/doc/nomicon/dot-operator.md
@@ -0,0 +1,6 @@
+% The Dot Operator
+
+The dot operator will perform a lot of magic to convert types. It will perform
+auto-referencing, auto-dereferencing, and coercion until types match.
+
+TODO: steal information from http://stackoverflow.com/questions/28519997/what-are-rusts-exact-auto-dereferencing-rules/28552082#28552082
diff --git a/src/doc/nomicon/drop-flags.md b/src/doc/nomicon/drop-flags.md
new file mode 100644
index 00000000000..1e81c97479b
--- /dev/null
+++ b/src/doc/nomicon/drop-flags.md
@@ -0,0 +1,95 @@
+% Drop Flags
+
+The examples in the previous section introduce an interesting problem for Rust.
+We have seen that's possible to conditionally initialize, deinitialize, and
+reinitialize locations of memory totally safely. For Copy types, this isn't
+particularly notable since they're just a random pile of bits. However types
+with destructors are a different story: Rust needs to know whether to call a
+destructor whenever a variable is assigned to, or a variable goes out of scope.
+How can it do this with conditional initialization?
+
+Note that this is not a problem that all assignments need worry about. In
+particular, assigning through a dereference unconditionally drops, and assigning
+in a `let` unconditionally doesn't drop:
+
+```
+let mut x = Box::new(0); // let makes a fresh variable, so never need to drop
+let y = &mut x;
+*y = Box::new(1); // Deref assumes the referent is initialized, so always drops
+```
+
+This is only a problem when overwriting a previously initialized variable or
+one of its subfields.
+
+It turns out that Rust actually tracks whether a type should be dropped or not
+*at runtime*. As a variable becomes initialized and uninitialized, a *drop flag*
+for that variable is toggled. When a variable might need to be dropped, this
+flag is evaluated to determine if it should be dropped.
+
+Of course, it is often the case that a value's initialization state can be
+statically known at every point in the program. If this is the case, then the
+compiler can theoretically generate more efficient code! For instance, straight-
+line code has such *static drop semantics*:
+
+```rust
+let mut x = Box::new(0); // x was uninit; just overwrite.
+let mut y = x;           // y was uninit; just overwrite and make x uninit.
+x = Box::new(0);         // x was uninit; just overwrite.
+y = x;                   // y was init; Drop y, overwrite it, and make x uninit!
+                         // y goes out of scope; y was init; Drop y!
+                         // x goes out of scope; x was uninit; do nothing.
+```
+
+Similarly, branched code where all branches have the same behaviour with respect
+to initialization has static drop semantics:
+
+```rust
+# let condition = true;
+let mut x = Box::new(0);    // x was uninit; just overwrite.
+if condition {
+    drop(x)                 // x gets moved out; make x uninit.
+} else {
+    println!("{}", x);
+    drop(x)                 // x gets moved out; make x uninit.
+}
+x = Box::new(0);            // x was uninit; just overwrite.
+                            // x goes out of scope; x was init; Drop x!
+```
+
+However code like this *requires* runtime information to correctly Drop:
+
+```rust
+# let condition = true;
+let x;
+if condition {
+    x = Box::new(0);        // x was uninit; just overwrite.
+    println!("{}", x);
+}
+                            // x goes out of scope; x might be uninit;
+                            // check the flag!
+```
+
+Of course, in this case it's trivial to retrieve static drop semantics:
+
+```rust
+# let condition = true;
+if condition {
+    let x = Box::new(0);
+    println!("{}", x);
+}
+```
+
+As of Rust 1.0, the drop flags are actually not-so-secretly stashed in a hidden
+field of any type that implements Drop. Rust sets the drop flag by overwriting
+the entire value with a particular bit pattern. This is pretty obviously Not
+The Fastest and causes a bunch of trouble with optimizing code. It's legacy from
+a time when you could do much more complex conditional initialization.
+
+As such work is currently under way to move the flags out onto the stack frame
+where they more reasonably belong. Unfortunately, this work will take some time
+as it requires fairly substantial changes to the compiler.
+
+Regardless, Rust programs don't need to worry about uninitialized values on
+the stack for correctness. Although they might care for performance. Thankfully,
+Rust makes it easy to take control here! Uninitialized values are there, and
+you can work with them in Safe Rust, but you're never in danger.
diff --git a/src/doc/nomicon/dropck.md b/src/doc/nomicon/dropck.md
new file mode 100644
index 00000000000..df09d1a1744
--- /dev/null
+++ b/src/doc/nomicon/dropck.md
@@ -0,0 +1,127 @@
+% Drop Check
+
+We have seen how lifetimes provide us some fairly simple rules for ensuring
+that never read dangling references. However up to this point we have only ever
+interacted with the *outlives* relationship in an inclusive manner. That is,
+when we talked about `'a: 'b`, it was ok for `'a` to live *exactly* as long as
+`'b`. At first glance, this seems to be a meaningless distinction. Nothing ever
+gets dropped at the same time as another, right? This is why we used the
+following desugarring of `let` statements:
+
+```rust,ignore
+let x;
+let y;
+```
+
+```rust,ignore
+{
+    let x;
+    {
+        let y;
+    }
+}
+```
+
+Each creates its own scope, clearly establishing that one drops before the
+other. However, what if we do the following?
+
+```rust,ignore
+let (x, y) = (vec![], vec![]);
+```
+
+Does either value strictly outlive the other? The answer is in fact *no*,
+neither value strictly outlives the other. Of course, one of x or y will be
+dropped before the other, but the actual order is not specified. Tuples aren't
+special in this regard; composite structures just don't guarantee their
+destruction order as of Rust 1.0.
+
+We *could* specify this for the fields of built-in composites like tuples and
+structs. However, what about something like Vec? Vec has to manually drop its
+elements via pure-library code. In general, anything that implements Drop has
+a chance to fiddle with its innards during its final death knell. Therefore
+the compiler can't sufficiently reason about the actual destruction order
+of the contents of any type that implements Drop.
+
+So why do we care? We care because if the type system isn't careful, it could
+accidentally make dangling pointers. Consider the following simple program:
+
+```rust
+struct Inspector<'a>(&'a u8);
+
+fn main() {
+    let (inspector, days);
+    days = Box::new(1);
+    inspector = Inspector(&days);
+}
+```
+
+This program is totally sound and compiles today. The fact that `days` does
+not *strictly* outlive `inspector` doesn't matter. As long as the `inspector`
+is alive, so is days.
+
+However if we add a destructor, the program will no longer compile!
+
+```rust,ignore
+struct Inspector<'a>(&'a u8);
+
+impl<'a> Drop for Inspector<'a> {
+    fn drop(&mut self) {
+        println!("I was only {} days from retirement!", self.0);
+    }
+}
+
+fn main() {
+    let (inspector, days);
+    days = Box::new(1);
+    inspector = Inspector(&days);
+    // Let's say `days` happens to get dropped first.
+    // Then when Inspector is dropped, it will try to read free'd memory!
+}
+```
+
+```text
+<anon>:12:28: 12:32 error: `days` does not live long enough
+<anon>:12     inspector = Inspector(&days);
+                                     ^~~~
+<anon>:9:11: 15:2 note: reference must be valid for the block at 9:10...
+<anon>:9 fn main() {
+<anon>:10     let (inspector, days);
+<anon>:11     days = Box::new(1);
+<anon>:12     inspector = Inspector(&days);
+<anon>:13     // Let's say `days` happens to get dropped first.
+<anon>:14     // Then when Inspector is dropped, it will try to read free'd memory!
+          ...
+<anon>:10:27: 15:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 10:26
+<anon>:10     let (inspector, days);
+<anon>:11     days = Box::new(1);
+<anon>:12     inspector = Inspector(&days);
+<anon>:13     // Let's say `days` happens to get dropped first.
+<anon>:14     // Then when Inspector is dropped, it will try to read free'd memory!
+<anon>:15 }
+```
+
+Implementing Drop lets the Inspector execute some arbitrary code during its
+death. This means it can potentially observe that types that are supposed to
+live as long as it does actually were destroyed first.
+
+Interestingly, only generic types need to worry about this. If they aren't
+generic, then the only lifetimes they can harbor are `'static`, which will truly
+live *forever*. This is why this problem is referred to as *sound generic drop*.
+Sound generic drop is enforced by the *drop checker*. As of this writing, some
+of the finer details of how the drop checker validates types is totally up in
+the air. However The Big Rule is the subtlety that we have focused on this whole
+section:
+
+**For a generic type to soundly implement drop, its generics arguments must
+strictly outlive it.**
+
+This rule is sufficient but not necessary to satisfy the drop checker. That is,
+if your type obeys this rule then it's definitely sound to drop. However
+there are special cases where you can fail to satisfy this, but still
+successfully pass the borrow checker. These are the precise rules that are
+currently up in the air.
+
+It turns out that when writing unsafe code, we generally don't need to
+worry at all about doing the right thing for the drop checker. However there
+is one special case that you need to worry about, which we will look at in
+the next section.
diff --git a/src/doc/nomicon/exception-safety.md b/src/doc/nomicon/exception-safety.md
new file mode 100644
index 00000000000..74f7831a72a
--- /dev/null
+++ b/src/doc/nomicon/exception-safety.md
@@ -0,0 +1,217 @@
+% Exception Safety
+
+Although programs should use unwinding sparingly, there's a lot of code that
+*can* panic. If you unwrap a None, index out of bounds, or divide by 0, your
+program will panic. On debug builds, every arithmetic operation can panic
+if it overflows. Unless you are very careful and tightly control what code runs,
+pretty much everything can unwind, and you need to be ready for it.
+
+Being ready for unwinding is often referred to as *exception safety*
+in the broader programming world. In Rust, there are two levels of exception
+safety that one may concern themselves with:
+
+* In unsafe code, we *must* be exception safe to the point of not violating
+  memory safety. We'll call this *minimal* exception safety.
+
+* In safe code, it is *good* to be exception safe to the point of your program
+  doing the right thing. We'll call this *maximal* exception safety.
+
+As is the case in many places in Rust, Unsafe code must be ready to deal with
+bad Safe code when it comes to unwinding. Code that transiently creates
+unsound states must be careful that a panic does not cause that state to be
+used. Generally this means ensuring that only non-panicking code is run while
+these states exist, or making a guard that cleans up the state in the case of
+a panic. This does not necessarily mean that the state a panic witnesses is a
+fully coherent state. We need only guarantee that it's a *safe* state.
+
+Most Unsafe code is leaf-like, and therefore fairly easy to make exception-safe.
+It controls all the code that runs, and most of that code can't panic. However
+it is not uncommon for Unsafe code to work with arrays of temporarily
+uninitialized data while repeatedly invoking caller-provided code. Such code
+needs to be careful and consider exception safety.
+
+
+
+
+
+## Vec::push_all
+
+`Vec::push_all` is a temporary hack to get extending a Vec by a slice reliably
+efficient without specialization. Here's a simple implementation:
+
+```rust,ignore
+impl<T: Clone> Vec<T> {
+    fn push_all(&mut self, to_push: &[T]) {
+        self.reserve(to_push.len());
+        unsafe {
+            // can't overflow because we just reserved this
+            self.set_len(self.len() + to_push.len());
+
+            for (i, x) in to_push.iter().enumerate() {
+                self.ptr().offset(i as isize).write(x.clone());
+            }
+        }
+    }
+}
+```
+
+We bypass `push` in order to avoid redundant capacity and `len` checks on the
+Vec that we definitely know has capacity. The logic is totally correct, except
+there's a subtle problem with our code: it's not exception-safe! `set_len`,
+`offset`, and `write` are all fine; `clone` is the panic bomb we over-looked.
+
+Clone is completely out of our control, and is totally free to panic. If it
+does, our function will exit early with the length of the Vec set too large. If
+the Vec is looked at or dropped, uninitialized memory will be read!
+
+The fix in this case is fairly simple. If we want to guarantee that the values
+we *did* clone are dropped, we can set the `len` every loop iteration. If we
+just want to guarantee that uninitialized memory can't be observed, we can set
+the `len` after the loop.
+
+
+
+
+
+## BinaryHeap::sift_up
+
+Bubbling an element up a heap is a bit more complicated than extending a Vec.
+The pseudocode is as follows:
+
+```text
+bubble_up(heap, index):
+    while index != 0 && heap[index] < heap[parent(index)]:
+        heap.swap(index, parent(index))
+        index = parent(index)
+
+```
+
+A literal transcription of this code to Rust is totally fine, but has an annoying
+performance characteristic: the `self` element is swapped over and over again
+uselessly. We would rather have the following:
+
+```text
+bubble_up(heap, index):
+    let elem = heap[index]
+    while index != 0 && element < heap[parent(index)]:
+        heap[index] = heap[parent(index)]
+        index = parent(index)
+    heap[index] = elem
+```
+
+This code ensures that each element is copied as little as possible (it is in
+fact necessary that elem be copied twice in general). However it now exposes
+some exception safety trouble! At all times, there exists two copies of one
+value. If we panic in this function something will be double-dropped.
+Unfortunately, we also don't have full control of the code: that comparison is
+user-defined!
+
+Unlike Vec, the fix isn't as easy here. One option is to break the user-defined
+code and the unsafe code into two separate phases:
+
+```text
+bubble_up(heap, index):
+    let end_index = index;
+    while end_index != 0 && heap[end_index] < heap[parent(end_index)]:
+        end_index = parent(end_index)
+
+    let elem = heap[index]
+    while index != end_index:
+        heap[index] = heap[parent(index)]
+        index = parent(index)
+    heap[index] = elem
+```
+
+If the user-defined code blows up, that's no problem anymore, because we haven't
+actually touched the state of the heap yet. Once we do start messing with the
+heap, we're working with only data and functions that we trust, so there's no
+concern of panics.
+
+Perhaps you're not happy with this design. Surely it's cheating! And we have
+to do the complex heap traversal *twice*! Alright, let's bite the bullet. Let's
+intermix untrusted and unsafe code *for reals*.
+
+If Rust had `try` and `finally` like in Java, we could do the following:
+
+```text
+bubble_up(heap, index):
+    let elem = heap[index]
+    try:
+        while index != 0 && element < heap[parent(index)]:
+            heap[index] = heap[parent(index)]
+            index = parent(index)
+    finally:
+        heap[index] = elem
+```
+
+The basic idea is simple: if the comparison panics, we just toss the loose
+element in the logically uninitialized index and bail out. Anyone who observes
+the heap will see a potentially *inconsistent* heap, but at least it won't
+cause any double-drops! If the algorithm terminates normally, then this
+operation happens to coincide precisely with the how we finish up regardless.
+
+Sadly, Rust has no such construct, so we're going to need to roll our own! The
+way to do this is to store the algorithm's state in a separate struct with a
+destructor for the "finally" logic. Whether we panic or not, that destructor
+will run and clean up after us.
+
+```rust,ignore
+struct Hole<'a, T: 'a> {
+    data: &'a mut [T],
+    /// `elt` is always `Some` from new until drop.
+    elt: Option<T>,
+    pos: usize,
+}
+
+impl<'a, T> Hole<'a, T> {
+    fn new(data: &'a mut [T], pos: usize) -> Self {
+        unsafe {
+            let elt = ptr::read(&data[pos]);
+            Hole {
+                data: data,
+                elt: Some(elt),
+                pos: pos,
+            }
+        }
+    }
+
+    fn pos(&self) -> usize { self.pos }
+
+    fn removed(&self) -> &T { self.elt.as_ref().unwrap() }
+
+    unsafe fn get(&self, index: usize) -> &T { &self.data[index] }
+
+    unsafe fn move_to(&mut self, index: usize) {
+        let index_ptr: *const _ = &self.data[index];
+        let hole_ptr = &mut self.data[self.pos];
+        ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1);
+        self.pos = index;
+    }
+}
+
+impl<'a, T> Drop for Hole<'a, T> {
+    fn drop(&mut self) {
+        // fill the hole again
+        unsafe {
+            let pos = self.pos;
+            ptr::write(&mut self.data[pos], self.elt.take().unwrap());
+        }
+    }
+}
+
+impl<T: Ord> BinaryHeap<T> {
+    fn sift_up(&mut self, pos: usize) {
+        unsafe {
+            // Take out the value at `pos` and create a hole.
+            let mut hole = Hole::new(&mut self.data, pos);
+
+            while hole.pos() != 0 {
+                let parent = parent(hole.pos());
+                if hole.removed() <= hole.get(parent) { break }
+                hole.move_to(parent);
+            }
+            // Hole will be unconditionally filled here; panic or not!
+        }
+    }
+}
+```
diff --git a/src/doc/nomicon/exotic-sizes.md b/src/doc/nomicon/exotic-sizes.md
new file mode 100644
index 00000000000..0b653a7ad3a
--- /dev/null
+++ b/src/doc/nomicon/exotic-sizes.md
@@ -0,0 +1,137 @@
+% Exotically Sized Types
+
+Most of the time, we think in terms of types with a fixed, positive size. This
+is not always the case, however.
+
+
+
+
+
+# Dynamically Sized Types (DSTs)
+
+Rust in fact supports Dynamically Sized Types (DSTs): types without a statically
+known size or alignment. On the surface, this is a bit nonsensical: Rust *must*
+know the size and alignment of something in order to correctly work with it! In
+this regard, DSTs are not normal types. Due to their lack of a statically known
+size, these types can only exist behind some kind of pointer. Any pointer to a
+DST consequently becomes a *fat* pointer consisting of the pointer and the
+information that "completes" them (more on this below).
+
+There are two major DSTs exposed by the language: trait objects, and slices.
+
+A trait object represents some type that implements the traits it specifies.
+The exact original type is *erased* in favour of runtime reflection
+with a vtable containing all the information necessary to use the type.
+This is the information that completes a trait object: a pointer to its vtable.
+
+A slice is simply a view into some contiguous storage -- typically an array or
+`Vec`. The information that completes a slice is just the number of elements
+it points to.
+
+Structs can actually store a single DST directly as their last field, but this
+makes them a DST as well:
+
+```rust
+// Can't be stored on the stack directly
+struct Foo {
+    info: u32,
+    data: [u8],
+}
+```
+
+**NOTE: [As of Rust 1.0 struct DSTs are broken if the last field has
+a variable position based on its alignment][dst-issue].**
+
+
+
+
+
+# Zero Sized Types (ZSTs)
+
+Rust actually allows types to be specified that occupy no space:
+
+```rust
+struct Foo; // No fields = no size
+
+// All fields have no size = no size
+struct Baz {
+    foo: Foo,
+    qux: (),      // empty tuple has no size
+    baz: [u8; 0], // empty array has no size
+}
+```
+
+On their own, Zero Sized Types (ZSTs) are, for obvious reasons, pretty useless.
+However as with many curious layout choices in Rust, their potential is realized
+in a generic context: Rust largely understands that any operation that  produces
+or stores a ZST can be reduced to a no-op. First off, storing it  doesn't even
+make sense -- it doesn't occupy any space. Also there's only one  value of that
+type, so anything that loads it can just produce it from the  aether -- which is
+also a no-op since it doesn't occupy any space.
+
+One of the most extreme example's of this is Sets and Maps. Given a
+`Map<Key, Value>`, it is common to implement a `Set<Key>` as just a thin wrapper
+around `Map<Key, UselessJunk>`. In many languages, this would necessitate
+allocating space for UselessJunk and doing work to store and load UselessJunk
+only to discard it. Proving this unnecessary would be a difficult analysis for
+the compiler.
+
+However in Rust, we can just say that  `Set<Key> = Map<Key, ()>`. Now Rust
+statically knows that every load and store is useless, and no allocation has any
+size. The result is that the monomorphized code is basically a custom
+implementation of a HashSet with none of the overhead that HashMap would have to
+support values.
+
+Safe code need not worry about ZSTs, but *unsafe* code must be careful about the
+consequence of types with no size. In particular, pointer offsets are no-ops,
+and standard allocators (including jemalloc, the one used by default in Rust)
+generally consider passing in `0` for the size of an allocation as Undefined
+Behaviour.
+
+
+
+
+
+# Empty Types
+
+Rust also enables types to be declared that *cannot even be instantiated*. These
+types can only be talked about at the type level, and never at the value level.
+Empty types can be declared by specifying an enum with no variants:
+
+```rust
+enum Void {} // No variants = EMPTY
+```
+
+Empty types are even more marginal than ZSTs. The primary motivating example for
+Void types is type-level unreachability. For instance, suppose an API needs to
+return a Result in general, but a specific case actually is infallible. It's
+actually possible to communicate this at the type level by returning a
+`Result<T, Void>`. Consumers of the API can confidently unwrap such a Result
+knowing that it's *statically impossible* for this value to be an `Err`, as
+this would require providing a value of type `Void`.
+
+In principle, Rust can do some interesting analyses and optimizations based
+on this fact. For instance, `Result<T, Void>` could be represented as just `T`,
+because the `Err` case doesn't actually exist. The following *could* also
+compile:
+
+```rust,ignore
+enum Void {}
+
+let res: Result<u32, Void> = Ok(0);
+
+// Err doesn't exist anymore, so Ok is actually irrefutable.
+let Ok(num) = res;
+```
+
+But neither of these tricks work today, so all Void types get you is
+the ability to be confident that certain situations are statically impossible.
+
+One final subtle detail about empty types is that raw pointers to them are
+actually valid to construct, but dereferencing them is Undefined Behaviour
+because that doesn't actually make sense. That is, you could model C's `void *`
+type with `*const Void`, but this doesn't necessarily gain anything over using
+e.g. `*const ()`, which *is* safe to randomly dereference.
+
+
+[dst-issue]: https://github.com/rust-lang/rust/issues/26403
diff --git a/src/doc/nomicon/hrtb.md b/src/doc/nomicon/hrtb.md
new file mode 100644
index 00000000000..8692832e2c7
--- /dev/null
+++ b/src/doc/nomicon/hrtb.md
@@ -0,0 +1,73 @@
+% Higher-Rank Trait Bounds (HRTBs)
+
+Rust's `Fn` traits are a little bit magic. For instance, we can write the
+following code:
+
+```rust
+struct Closure<F> {
+    data: (u8, u16),
+    func: F,
+}
+
+impl<F> Closure<F>
+    where F: Fn(&(u8, u16)) -> &u8,
+{
+    fn call(&self) -> &u8 {
+        (self.func)(&self.data)
+    }
+}
+
+fn do_it(data: &(u8, u16)) -> &u8 { &data.0 }
+
+fn main() {
+    let clo = Closure { data: (0, 1), func: do_it };
+    println!("{}", clo.call());
+}
+```
+
+If we try to naively desugar this code in the same way that we did in the
+lifetimes section, we run into some trouble:
+
+```rust,ignore
+struct Closure<F> {
+    data: (u8, u16),
+    func: F,
+}
+
+impl<F> Closure<F>
+    // where F: Fn(&'??? (u8, u16)) -> &'??? u8,
+{
+    fn call<'a>(&'a self) -> &'a u8 {
+        (self.func)(&self.data)
+    }
+}
+
+fn do_it<'b>(data: &'b (u8, u16)) -> &'b u8 { &'b data.0 }
+
+fn main() {
+    'x: {
+        let clo = Closure { data: (0, 1), func: do_it };
+        println!("{}", clo.call());
+    }
+}
+```
+
+How on earth are we supposed to express the lifetimes on `F`'s trait bound? We
+need to provide some lifetime there, but the lifetime we care about can't be
+named until we enter the body of `call`! Also, that isn't some fixed lifetime;
+`call` works with *any* lifetime `&self` happens to have at that point.
+
+This job requires The Magic of Higher-Rank Trait Bounds (HRTBs). The way we
+desugar this is as follows:
+
+```rust,ignore
+where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
+```
+
+(Where `Fn(a, b, c) -> d` is itself just sugar for the unstable *real* `Fn`
+trait)
+
+`for<'a>` can be read as "for all choices of `'a`", and basically produces an
+*infinite list* of trait bounds that F must satisfy. Intense. There aren't many
+places outside of the `Fn` traits where we encounter HRTBs, and even for
+those we have a nice magic sugar for the common cases.
diff --git a/src/doc/nomicon/leaking.md b/src/doc/nomicon/leaking.md
new file mode 100644
index 00000000000..1aa78e112ea
--- /dev/null
+++ b/src/doc/nomicon/leaking.md
@@ -0,0 +1,252 @@
+% Leaking
+
+Ownership-based resource management is intended to simplify composition. You
+acquire resources when you create the object, and you release the resources when
+it gets destroyed. Since destruction is handled for you, it means you can't
+forget to release the resources, and it happens as soon as possible! Surely this
+is perfect and all of our problems are solved.
+
+Everything is terrible and we have new and exotic problems to try to solve.
+
+Many people like to believe that Rust eliminates resource leaks. In practice,
+this is basically true. You would be surprised to see a Safe Rust program
+leak resources in an uncontrolled way.
+
+However from a theoretical perspective this is absolutely not the case, no
+matter how you look at it. In the strictest sense, "leaking" is so abstract as
+to be unpreventable. It's quite trivial to initialize a collection at the start
+of a program, fill it with tons of objects with destructors, and then enter an
+infinite event loop that never refers to it. The collection will sit around
+uselessly, holding on to its precious resources until the program terminates (at
+which point all those resources would have been reclaimed by the OS anyway).
+
+We may consider a more restricted form of leak: failing to drop a value that is
+unreachable. Rust also doesn't prevent this. In fact Rust *has a function for
+doing this*: `mem::forget`. This function consumes the value it is passed *and
+then doesn't run its destructor*.
+
+In the past `mem::forget` was marked as unsafe as a sort of lint against using
+it, since failing to call a destructor is generally not a well-behaved thing to
+do (though useful for some special unsafe code). However this was generally
+determined to be an untenable stance to take: there are many ways to fail to
+call a destructor in safe code. The most famous example is creating a cycle of
+reference-counted pointers using interior mutability.
+
+It is reasonable for safe code to assume that destructor leaks do not happen, as
+any program that leaks destructors is probably wrong. However *unsafe* code
+cannot rely on destructors to be run in order to be safe. For most types this
+doesn't matter: if you leak the destructor then the type is by definition
+inaccessible, so it doesn't matter, right? For instance, if you leak a `Box<u8>`
+then you waste some memory but that's hardly going to violate memory-safety.
+
+However where we must be careful with destructor leaks are *proxy* types. These
+are types which manage access to a distinct object, but don't actually own it.
+Proxy objects are quite rare. Proxy objects you'll need to care about are even
+rarer. However we'll focus on three interesting examples in the standard
+library:
+
+* `vec::Drain`
+* `Rc`
+* `thread::scoped::JoinGuard`
+
+
+
+## Drain
+
+`drain` is a collections API that moves data out of the container without
+consuming the container. This enables us to reuse the allocation of a `Vec`
+after claiming ownership over all of its contents. It produces an iterator
+(Drain) that returns the contents of the Vec by-value.
+
+Now, consider Drain in the middle of iteration: some values have been moved out,
+and others haven't. This means that part of the Vec is now full of logically
+uninitialized data! We could backshift all the elements in the Vec every time we
+remove a value, but this would have pretty catastrophic performance
+consequences.
+
+Instead, we would like Drain to fix the Vec's backing storage when it is
+dropped. It should run itself to completion, backshift any elements that weren't
+removed (drain supports subranges), and then fix Vec's `len`. It's even
+unwinding-safe! Easy!
+
+Now consider the following:
+
+```rust,ignore
+let mut vec = vec![Box::new(0); 4];
+
+{
+    // start draining, vec can no longer be accessed
+    let mut drainer = vec.drain(..);
+
+    // pull out two elements and immediately drop them
+    drainer.next();
+    drainer.next();
+
+    // get rid of drainer, but don't call its destructor
+    mem::forget(drainer);
+}
+
+// Oops, vec[0] was dropped, we're reading a pointer into free'd memory!
+println!("{}", vec[0]);
+```
+
+This is pretty clearly Not Good. Unfortunately, we're kind've stuck between a
+rock and a hard place: maintaining consistent state at every step has an
+enormous cost (and would negate any benefits of the API). Failing to maintain
+consistent state gives us Undefined Behaviour in safe code (making the API
+unsound).
+
+So what can we do? Well, we can pick a trivially consistent state: set the Vec's
+len to be 0 when we start the iteration, and fix it up if necessary in the
+destructor. That way, if everything executes like normal we get the desired
+behaviour with minimal overhead. But if someone has the *audacity* to
+mem::forget us in the middle of the iteration, all that does is *leak even more*
+(and possibly leave the Vec in an unexpected but otherwise consistent state).
+Since we've accepted that mem::forget is safe, this is definitely safe. We call
+leaks causing more leaks a *leak amplification*.
+
+
+
+
+## Rc
+
+Rc is an interesting case because at first glance it doesn't appear to be a
+proxy value at all. After all, it manages the data it points to, and dropping
+all the Rcs for a value will drop that value. Leaking an Rc doesn't seem like it
+would be particularly dangerous. It will leave the refcount permanently
+incremented and prevent the data from being freed or dropped, but that seems
+just like Box, right?
+
+Nope.
+
+Let's consider a simplified implementation of Rc:
+
+```rust,ignore
+struct Rc<T> {
+    ptr: *mut RcBox<T>,
+}
+
+struct RcBox<T> {
+    data: T,
+    ref_count: usize,
+}
+
+impl<T> Rc<T> {
+    fn new(data: T) -> Self {
+        unsafe {
+            // Wouldn't it be nice if heap::allocate worked like this?
+            let ptr = heap::allocate<RcBox<T>>();
+            ptr::write(ptr, RcBox {
+                data: data,
+                ref_count: 1,
+            });
+            Rc { ptr: ptr }
+        }
+    }
+
+    fn clone(&self) -> Self {
+        unsafe {
+            (*self.ptr).ref_count += 1;
+        }
+        Rc { ptr: self.ptr }
+    }
+}
+
+impl<T> Drop for Rc<T> {
+    fn drop(&mut self) {
+        unsafe {
+            let inner = &mut ;
+            (*self.ptr).ref_count -= 1;
+            if (*self.ptr).ref_count == 0 {
+                // drop the data and then free it
+                ptr::read(self.ptr);
+                heap::deallocate(self.ptr);
+            }
+        }
+    }
+}
+```
+
+This code contains an implicit and subtle assumption: `ref_count` can fit in a
+`usize`, because there can't be more than `usize::MAX` Rcs in memory. However
+this itself assumes that the `ref_count` accurately reflects the number of Rcs
+in memory, which we know is false with `mem::forget`. Using `mem::forget` we can
+overflow the `ref_count`, and then get it down to 0 with outstanding Rcs. Then
+we can happily use-after-free the inner data. Bad Bad Not Good.
+
+This can be solved by just checking the `ref_count` and doing *something*. The
+standard library's stance is to just abort, because your program has become
+horribly degenerate. Also *oh my gosh* it's such a ridiculous corner case.
+
+
+
+
+## thread::scoped::JoinGuard
+
+The thread::scoped API intends to allow threads to be spawned that reference
+data on their parent's stack without any synchronization over that data by
+ensuring the parent joins the thread before any of the shared data goes out
+of scope.
+
+```rust,ignore
+pub fn scoped<'a, F>(f: F) -> JoinGuard<'a>
+    where F: FnOnce() + Send + 'a
+```
+
+Here `f` is some closure for the other thread to execute. Saying that
+`F: Send +'a` is saying that it closes over data that lives for `'a`, and it
+either owns that data or the data was Sync (implying `&data` is Send).
+
+Because JoinGuard has a lifetime, it keeps all the data it closes over
+borrowed in the parent thread. This means the JoinGuard can't outlive
+the data that the other thread is working on. When the JoinGuard *does* get
+dropped it blocks the parent thread, ensuring the child terminates before any
+of the closed-over data goes out of scope in the parent.
+
+Usage looked like:
+
+```rust,ignore
+let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+{
+    let guards = vec![];
+    for x in &mut data {
+        // Move the mutable reference into the closure, and execute
+        // it on a different thread. The closure has a lifetime bound
+        // by the lifetime of the mutable reference `x` we store in it.
+        // The guard that is returned is in turn assigned the lifetime
+        // of the closure, so it also mutably borrows `data` as `x` did.
+        // This means we cannot access `data` until the guard goes away.
+        let guard = thread::scoped(move || {
+            *x *= 2;
+        });
+        // store the thread's guard for later
+        guards.push(guard);
+    }
+    // All guards are dropped here, forcing the threads to join
+    // (this thread blocks here until the others terminate).
+    // Once the threads join, the borrow expires and the data becomes
+    // accessible again in this thread.
+}
+// data is definitely mutated here.
+```
+
+In principle, this totally works! Rust's ownership system perfectly ensures it!
+...except it relies on a destructor being called to be safe.
+
+```rust,ignore
+let mut data = Box::new(0);
+{
+    let guard = thread::scoped(|| {
+        // This is at best a data race. At worst, it's also a use-after-free.
+        *data += 1;
+    });
+    // Because the guard is forgotten, expiring the loan without blocking this
+    // thread.
+    mem::forget(guard);
+}
+// So the Box is dropped here while the scoped thread may or may not be trying
+// to access it.
+```
+
+Dang. Here the destructor running was pretty fundamental to the API, and it had
+to be scrapped in favour of a completely different design.
diff --git a/src/doc/nomicon/lifetime-elision.md b/src/doc/nomicon/lifetime-elision.md
new file mode 100644
index 00000000000..41014f46dd9
--- /dev/null
+++ b/src/doc/nomicon/lifetime-elision.md
@@ -0,0 +1,64 @@
+% Lifetime Elision
+
+In order to make common patterns more ergonomic, Rust allows lifetimes to be
+*elided* in function signatures.
+
+A *lifetime position* is anywhere you can write a lifetime in a type:
+
+```rust,ignore
+&'a T
+&'a mut T
+T<'a>
+```
+
+Lifetime positions can appear as either "input" or "output":
+
+* For `fn` definitions, input refers to the types of the formal arguments
+  in the `fn` definition, while output refers to
+  result types. So `fn foo(s: &str) -> (&str, &str)` has elided one lifetime in
+  input position and two lifetimes in output position.
+  Note that the input positions of a `fn` method definition do not
+  include the lifetimes that occur in the method's `impl` header
+  (nor lifetimes that occur in the trait header, for a default method).
+
+* In the future, it should be possible to elide `impl` headers in the same manner.
+
+Elision rules are as follows:
+
+* Each elided lifetime in input position becomes a distinct lifetime
+  parameter.
+
+* If there is exactly one input lifetime position (elided or not), that lifetime
+  is assigned to *all* elided output lifetimes.
+
+* If there are multiple input lifetime positions, but one of them is `&self` or
+  `&mut self`, the lifetime of `self` is assigned to *all* elided output lifetimes.
+
+* Otherwise, it is an error to elide an output lifetime.
+
+Examples:
+
+```rust,ignore
+fn print(s: &str);                                      // elided
+fn print<'a>(s: &'a str);                               // expanded
+
+fn debug(lvl: uint, s: &str);                           // elided
+fn debug<'a>(lvl: uint, s: &'a str);                    // expanded
+
+fn substr(s: &str, until: uint) -> &str;                // elided
+fn substr<'a>(s: &'a str, until: uint) -> &'a str;      // expanded
+
+fn get_str() -> &str;                                   // ILLEGAL
+
+fn frob(s: &str, t: &str) -> &str;                      // ILLEGAL
+
+fn get_mut(&mut self) -> &mut T;                        // elided
+fn get_mut<'a>(&'a mut self) -> &'a mut T;              // expanded
+
+fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command                  // elided
+fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
+
+fn new(buf: &mut [u8]) -> BufWriter;                    // elided
+fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>          // expanded
+
+```
diff --git a/src/doc/nomicon/lifetime-mismatch.md b/src/doc/nomicon/lifetime-mismatch.md
new file mode 100644
index 00000000000..8b01616ee0d
--- /dev/null
+++ b/src/doc/nomicon/lifetime-mismatch.md
@@ -0,0 +1,81 @@
+% Limits of Lifetimes
+
+Given the following code:
+
+```rust,ignore
+struct Foo;
+
+impl Foo {
+    fn mutate_and_share(&mut self) -> &Self { &*self }
+    fn share(&self) {}
+}
+
+fn main() {
+    let mut foo = Foo;
+    let loan = foo.mutate_and_share();
+    foo.share();
+}
+```
+
+One might expect it to compile. We call `mutate_and_share`, which mutably borrows
+`foo` temporarily, but then returns only a shared reference. Therefore we
+would expect `foo.share()` to succeed as `foo` shouldn't be mutably borrowed.
+
+However when we try to compile it:
+
+```text
+<anon>:11:5: 11:8 error: cannot borrow `foo` as immutable because it is also borrowed as mutable
+<anon>:11     foo.share();
+              ^~~
+<anon>:10:16: 10:19 note: previous borrow of `foo` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `foo` until the borrow ends
+<anon>:10     let loan = foo.mutate_and_share();
+                         ^~~
+<anon>:12:2: 12:2 note: previous borrow ends here
+<anon>:8 fn main() {
+<anon>:9     let mut foo = Foo;
+<anon>:10     let loan = foo.mutate_and_share();
+<anon>:11     foo.share();
+<anon>:12 }
+          ^
+```
+
+What happened? Well, we got the exact same reasoning as we did for
+[Example 2 in the previous section][ex2]. We desugar the program and we get
+the following:
+
+```rust,ignore
+struct Foo;
+
+impl Foo {
+    fn mutate_and_share<'a>(&'a mut self) -> &'a Self { &'a *self }
+    fn share<'a>(&'a self) {}
+}
+
+fn main() {
+	'b: {
+    	let mut foo: Foo = Foo;
+    	'c: {
+    		let loan: &'c Foo = Foo::mutate_and_share::<'c>(&'c mut foo);
+    		'd: {
+    			Foo::share::<'d>(&'d foo);
+    		}
+    	}
+    }
+}
+```
+
+The lifetime system is forced to extend the `&mut foo` to have lifetime `'c`,
+due to the lifetime of `loan` and mutate_and_share's signature. Then when we
+try to call `share`, and it sees we're trying to alias that `&'c mut foo` and
+blows up in our face!
+
+This program is clearly correct according to the reference semantics we actually
+care about, but the lifetime system is too coarse-grained to handle that.
+
+
+TODO: other common problems? SEME regions stuff, mostly?
+
+
+
+
+[ex2]: lifetimes.html#example-2:-aliasing-a-mutable-reference
diff --git a/src/doc/nomicon/lifetimes.md b/src/doc/nomicon/lifetimes.md
new file mode 100644
index 00000000000..f211841ec0c
--- /dev/null
+++ b/src/doc/nomicon/lifetimes.md
@@ -0,0 +1,216 @@
+% Lifetimes
+
+Rust enforces these rules through *lifetimes*. Lifetimes are effectively
+just names for scopes somewhere in the program. Each reference,
+and anything that contains a reference, is tagged with a lifetime specifying
+the scope it's valid for.
+
+Within a function body, Rust generally doesn't let you explicitly name the
+lifetimes involved. This is because it's generally not really necessary
+to talk about lifetimes in a local context; Rust has all the information and
+can work out everything as optimally as possible. Many anonymous scopes and
+temporaries that you would otherwise have to write are often introduced to
+make your code Just Work.
+
+However once you cross the function boundary, you need to start talking about
+lifetimes. Lifetimes are denoted with an apostrophe: `'a`, `'static`. To dip
+our toes with lifetimes, we're going to pretend that we're actually allowed
+to label scopes with lifetimes, and desugar the examples from the start of
+this chapter.
+
+Originally, our examples made use of *aggressive* sugar -- high fructose corn
+syrup even -- around scopes and lifetimes, because writing everything out
+explicitly is *extremely noisy*. All Rust code relies on aggressive inference
+and elision of "obvious" things.
+
+One particularly interesting piece of sugar is that each `let` statement implicitly
+introduces a scope. For the most part, this doesn't really matter. However it
+does matter for variables that refer to each other. As a simple example, let's
+completely desugar this simple piece of Rust code:
+
+```rust
+let x = 0;
+let y = &x;
+let z = &y;
+```
+
+The borrow checker always tries to minimize the extent of a lifetime, so it will
+likely desugar to the following:
+
+```rust,ignore
+// NOTE: `'a: {` and `&'b x` is not valid syntax!
+'a: {
+    let x: i32 = 0;
+    'b: {
+        // lifetime used is 'b because that's good enough.
+        let y: &'b i32 = &'b x;
+        'c: {
+            // ditto on 'c
+            let z: &'c &'b i32 = &'c y;
+        }
+    }
+}
+```
+
+Wow. That's... awful. Let's all take a moment to thank Rust for being a
+diabetes-inducing torrent of syrupy-goodness.
+
+Actually passing references to outer scopes will cause Rust to infer
+a larger lifetime:
+
+```rust
+let x = 0;
+let z;
+let y = &x;
+z = y;
+```
+
+```rust,ignore
+'a: {
+    let x: i32 = 0;
+    'b: {
+        let z: &'b i32;
+        'c: {
+            // Must use 'b here because this reference is
+            // being passed to that scope.
+            let y: &'b i32 = &'b x;
+            z = y;
+        }
+    }
+}
+```
+
+
+
+# Example: references that outlive referents
+
+Alright, let's look at some of those examples from before:
+
+```rust,ignore
+fn as_str(data: &u32) -> &str {
+    let s = format!("{}", data);
+    &s
+}
+```
+
+desugars to:
+
+```rust,ignore
+fn as_str<'a>(data: &'a u32) -> &'a str {
+    'b: {
+        let s = format!("{}", data);
+        return &'a s;
+    }
+}
+```
+
+This signature of `as_str` takes a reference to a u32 with *some* lifetime, and
+promises that it can produce a reference to a str that can live *just as long*.
+Already we can see why this signature might be trouble. That basically implies
+that we're going to find a str somewhere in the scope the reference
+to the u32 originated in, or somewhere *even earlier*. That's a bit of a big
+ask.
+
+We then proceed to compute the string `s`, and return a reference to it. Since
+the contract of our function says the reference must outlive `'a`, that's the
+lifetime we infer for the reference. Unfortunately, `s` was defined in the
+scope `'b`, so the only way this is sound is if `'b` contains `'a` -- which is
+clearly false since `'a` must contain the function call itself. We have therefore
+created a reference whose lifetime outlives its referent, which is *literally*
+the first thing we said that references can't do. The compiler rightfully blows
+up in our face.
+
+To make this more clear, we can expand the example:
+
+```rust,ignore
+fn as_str<'a>(data: &'a u32) -> &'a str {
+    'b: {
+        let s = format!("{}", data);
+        return &'a s
+    }
+}
+
+fn main() {
+    'c: {
+        let x: u32 = 0;
+        'd: {
+            // An anonymous scope is introduced because the borrow does not
+            // need to last for the whole scope x is valid for. The return
+            // of as_str must find a str somewhere before this function
+            // call. Obviously not happening.
+            println!("{}", as_str::<'d>(&'d x));
+        }
+    }
+}
+```
+
+Shoot!
+
+Of course, the right way to write this function is as follows:
+
+```rust
+fn to_string(data: &u32) -> String {
+    format!("{}", data)
+}
+```
+
+We must produce an owned value inside the function to return it! The only way
+we could have returned an `&'a str` would have been if it was in a field of the
+`&'a u32`, which is obviously not the case.
+
+(Actually we could have also just returned a string literal, which as a global
+can be considered to reside at the bottom of the stack; though this limits
+our implementation *just a bit*.)
+
+
+
+
+
+# Example: aliasing a mutable reference
+
+How about the other example:
+
+```rust,ignore
+let mut data = vec![1, 2, 3];
+let x = &data[0];
+data.push(4);
+println!("{}", x);
+```
+
+```rust,ignore
+'a: {
+    let mut data: Vec<i32> = vec![1, 2, 3];
+    'b: {
+        // 'b is as big as we need this borrow to be
+        // (just need to get to `println!`)
+        let x: &'b i32 = Index::index::<'b>(&'b data, 0);
+        'c: {
+            // Temporary scope because we don't need the
+            // &mut to last any longer.
+            Vec::push(&'c mut data, 4);
+        }
+        println!("{}", x);
+    }
+}
+```
+
+The problem here is is bit more subtle and interesting. We want Rust to
+reject this program for the following reason: We have a live shared reference `x`
+to a descendent of `data` when we try to take a mutable reference to `data`
+to `push`. This would create an aliased mutable reference, which would
+violate the *second* rule of references.
+
+However this is *not at all* how Rust reasons that this program is bad. Rust
+doesn't understand that `x` is a reference to a subpath of `data`. It doesn't
+understand Vec at all. What it *does* see is that `x` has to live for `'b` to
+be printed. The signature of `Index::index` subsequently demands that the
+reference we take to `data` has to survive for `'b`. When we try to call `push`,
+it then sees us try to make an `&'c mut data`. Rust knows that `'c` is contained
+within `'b`, and rejects our program because the `&'b data` must still be live!
+
+Here we see that the lifetime system is much more coarse than the reference
+semantics we're actually interested in preserving. For the most part, *that's
+totally ok*, because it keeps us from spending all day explaining our program
+to the compiler. However it does mean that several programs that are totally
+correct with respect to Rust's *true* semantics are rejected because lifetimes
+are too dumb.
diff --git a/src/doc/nomicon/meet-safe-and-unsafe.md b/src/doc/nomicon/meet-safe-and-unsafe.md
new file mode 100644
index 00000000000..15e49c747b8
--- /dev/null
+++ b/src/doc/nomicon/meet-safe-and-unsafe.md
@@ -0,0 +1,98 @@
+% Meet Safe and Unsafe
+
+Programmers in safe "high-level" languages face a fundamental dilemma. On one
+hand, it would be *really* great to just say what you want and not worry about
+how it's done. On the other hand, that can lead to unacceptably poor
+performance. It may be necessary to drop down to less clear or idiomatic
+practices to get the performance characteristics you want. Or maybe you just
+throw up your hands in disgust and decide to shell out to an implementation in
+a less sugary-wonderful *unsafe* language.
+
+Worse, when you want to talk directly to the operating system, you *have* to
+talk to an unsafe language: *C*. C is ever-present and unavoidable. It's the
+lingua-franca of the programming world.
+Even other safe languages generally expose C interfaces for the world at large!
+Regardless of why you're doing it, as soon as your program starts talking to
+C it stops being safe.
+
+With that said, Rust is *totally* a safe programming language.
+
+Well, Rust *has* a safe programming language. Let's step back a bit.
+
+Rust can be thought of as being composed of two programming languages: *Safe
+Rust* and *Unsafe Rust*. Safe Rust is For Reals  Totally Safe. Unsafe Rust,
+unsurprisingly, is *not* For Reals Totally Safe.  In fact, Unsafe Rust lets you
+do some really crazy unsafe things.
+
+Safe Rust is the *true* Rust programming language. If all you do is write Safe
+Rust, you will never have to worry about type-safety or memory-safety. You will
+never endure a null or dangling pointer, or any of that Undefined Behaviour
+nonsense.
+
+*That's totally awesome.*
+
+The standard library also gives you enough utilities out-of-the-box that you'll
+be able to write awesome high-performance applications and libraries in pure
+idiomatic Safe Rust.
+
+But maybe you want to talk to another language. Maybe you're writing a
+low-level abstraction not exposed by the standard library. Maybe you're
+*writing* the standard library (which is written entirely in Rust). Maybe you
+need to do something the type-system doesn't understand and just *frob some dang
+bits*. Maybe you need Unsafe Rust.
+
+Unsafe Rust is exactly like Safe Rust with all the same rules and semantics.
+However Unsafe Rust lets you do some *extra* things that are Definitely Not Safe.
+
+The only things that are different in Unsafe Rust are that you can:
+
+* Dereference raw pointers
+* Call `unsafe` functions (including C functions, intrinsics, and the raw allocator)
+* Implement `unsafe` traits
+* Mutate statics
+
+That's it. The reason these operations are relegated to Unsafe is that misusing
+any of these things will cause the ever dreaded Undefined Behaviour. Invoking
+Undefined Behaviour gives the compiler full rights to do arbitrarily bad things
+to your program. You definitely *should not* invoke Undefined Behaviour.
+
+Unlike C, Undefined Behaviour is pretty limited in scope in Rust. All the core
+language cares about is preventing the following things:
+
+* Dereferencing null or dangling pointers
+* Reading [uninitialized memory][]
+* Breaking the [pointer aliasing rules][]
+* Producing invalid primitive values:
+    * dangling/null references
+    * a `bool` that isn't 0 or 1
+    * an undefined `enum` discriminant
+    * a `char` outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF]
+    * A non-utf8 `str`
+* Unwinding into another language
+* Causing a [data race][race]
+
+That's it. That's all the causes of Undefined Behaviour baked into Rust. Of
+course, unsafe functions and traits are free to declare arbitrary other
+constraints that a program must maintain to avoid Undefined Behaviour. However,
+generally violations of these constraints will just transitively lead to one of
+the above problems. Some additional constraints may also derive from compiler
+intrinsics that make special assumptions about how code can be optimized.
+
+Rust is otherwise quite permissive with respect to other dubious operations.
+Rust considers it "safe" to:
+
+* Deadlock
+* Have a [race condition][race]
+* Leak memory
+* Fail to call destructors
+* Overflow integers
+* Abort the program
+* Delete the production database
+
+However any program that actually manages to do such a thing is *probably*
+incorrect. Rust provides lots of tools to make these things rare, but
+these problems are considered impractical to categorically prevent.
+
+[pointer aliasing rules]: references.html
+[uninitialized memory]: uninitialized.html
+[race]: races.html
diff --git a/src/doc/nomicon/obrm.md b/src/doc/nomicon/obrm.md
new file mode 100644
index 00000000000..2c495240c12
--- /dev/null
+++ b/src/doc/nomicon/obrm.md
@@ -0,0 +1,14 @@
+% The Perils Of Ownership Based Resource Management (OBRM)
+
+OBRM (AKA RAII: Resource Acquisition Is Initialization) is something you'll
+interact with a lot in Rust. Especially if you use the standard library.
+
+Roughly speaking the pattern is as follows: to acquire a resource, you create an
+object that manages it. To release the resource, you simply destroy the object,
+and it cleans up the resource for you. The most common "resource" this pattern
+manages is simply *memory*. `Box`, `Rc`, and basically everything in
+`std::collections` is a convenience to enable correctly managing memory. This is
+particularly important in Rust because we have no pervasive GC to rely on for
+memory management. Which is the point, really: Rust is about control. However we
+are not limited to just memory. Pretty much every other system resource like a
+thread, file, or socket is exposed through this kind of API.
diff --git a/src/doc/nomicon/other-reprs.md b/src/doc/nomicon/other-reprs.md
new file mode 100644
index 00000000000..93ef2c13cdf
--- /dev/null
+++ b/src/doc/nomicon/other-reprs.md
@@ -0,0 +1,76 @@
+% Alternative representations
+
+Rust allows you to specify alternative data layout strategies from the default.
+
+
+
+
+# repr(C)
+
+This is the most important `repr`. It has fairly simple intent: do what C does.
+The order, size, and alignment of fields is exactly what you would expect from C
+or C++. Any type you expect to pass through an FFI boundary should have
+`repr(C)`, as C is the lingua-franca of the programming world. This is also
+necessary to soundly do more elaborate tricks with data layout such as
+reinterpreting values as a different type.
+
+However, the interaction with Rust's more exotic data layout features must be
+kept in mind. Due to its dual purpose as "for FFI" and "for layout control",
+`repr(C)` can be applied to types that will be nonsensical or problematic if
+passed through the FFI boundary.
+
+* ZSTs are still zero-sized, even though this is not a standard behaviour in
+C, and is explicitly contrary to the behaviour of an empty type in C++, which
+still consumes a byte of space.
+
+* DSTs, tuples, and tagged unions are not a concept in C and as such are never
+FFI safe.
+
+* **If the type would have any [drop flags][], they will still be added**
+
+* This is equivalent to one of `repr(u*)` (see the next section) for enums. The
+chosen size is the default enum size for the target platform's C ABI. Note that
+enum representation in C is implementation defined, so this is really a "best
+guess". In particular, this may be incorrect when the C code of interest is
+compiled with certain flags.
+
+
+
+# repr(u8), repr(u16), repr(u32), repr(u64)
+
+These specify the size to make a C-like enum. If the discriminant overflows the
+integer it has to fit in, it will produce a compile-time error. You can manually
+ask Rust to allow this by setting the overflowing element to explicitly be 0.
+However Rust will not allow you to create an enum where two variants have the
+same discriminant.
+
+On non-C-like enums, this will inhibit certain optimizations like the null-
+pointer optimization.
+
+These reprs have no effect on a struct.
+
+
+
+
+# repr(packed)
+
+`repr(packed)` forces rust to strip any padding, and only align the type to a
+byte. This may improve the memory footprint, but will likely have other negative
+side-effects.
+
+In particular, most architectures *strongly* prefer values to be aligned. This
+may mean the unaligned loads are penalized (x86), or even fault (some ARM
+chips). For simple cases like directly loading or storing a packed field, the
+compiler might be able to paper over alignment issues with shifts and masks.
+However if you take a reference to a packed field, it's unlikely that the
+compiler will be able to emit code to avoid an unaligned load.
+
+**[As of Rust 1.0 this can cause undefined behaviour.][ub loads]**
+
+`repr(packed)` is not to be used lightly. Unless you have extreme requirements,
+this should not be used.
+
+This repr is a modifier on `repr(C)` and `repr(rust)`.
+
+[drop flags]: drop-flags.html
+[ub loads]: https://github.com/rust-lang/rust/issues/27060
diff --git a/src/doc/nomicon/ownership.md b/src/doc/nomicon/ownership.md
new file mode 100644
index 00000000000..e80c64c3543
--- /dev/null
+++ b/src/doc/nomicon/ownership.md
@@ -0,0 +1,67 @@
+% Ownership and Lifetimes
+
+Ownership is the breakout feature of Rust. It allows Rust to be completely
+memory-safe and efficient, while avoiding garbage collection. Before getting
+into the ownership system in detail, we will consider the motivation of this
+design.
+
+We will assume that you accept that garbage collection (GC) is not always an
+optimal solution, and that it is desirable to manually manage memory in some
+contexts. If you do not accept this, might I interest you in a different
+language?
+
+Regardless of your feelings on GC, it is pretty clearly a *massive* boon to
+making code safe. You never have to worry about things going away *too soon*
+(although whether you still wanted to be pointing at that thing is a different
+issue...). This is a pervasive problem that C and C++ programs need to deal
+with. Consider this simple mistake that all of us who have used a non-GC'd
+language have made at one point:
+
+```rust,ignore
+fn as_str(data: &u32) -> &str {
+    // compute the string
+    let s = format!("{}", data);
+
+    // OH NO! We returned a reference to something that
+    // exists only in this function!
+    // Dangling pointer! Use after free! Alas!
+    // (this does not compile in Rust)
+    &s
+}
+```
+
+This is exactly what Rust's ownership system was built to solve.
+Rust knows the scope in which the `&s` lives, and as such can prevent it from
+escaping. However this is a simple case that even a C compiler could plausibly
+catch. Things get more complicated as code gets bigger and pointers get fed through
+various functions. Eventually, a C compiler will fall down and won't be able to
+perform sufficient escape analysis to prove your code unsound. It will consequently
+be forced to accept your program on the assumption that it is correct.
+
+This will never happen to Rust. It's up to the programmer to prove to the
+compiler that everything is sound.
+
+Of course, Rust's story around ownership is much more complicated than just
+verifying that references don't escape the scope of their referent. That's
+because ensuring pointers are always valid is much more complicated than this.
+For instance in this code,
+
+```rust,ignore
+let mut data = vec![1, 2, 3];
+// get an internal reference
+let x = &data[0];
+
+// OH NO! `push` causes the backing storage of `data` to be reallocated.
+// Dangling pointer! User after free! Alas!
+// (this does not compile in Rust)
+data.push(4);
+
+println!("{}", x);
+```
+
+naive scope analysis would be insufficient to prevent this bug, because `data`
+does in fact live as long as we needed. However it was *changed* while we had
+a reference into it. This is why Rust requires any references to freeze the
+referent and its owners.
+
+
diff --git a/src/doc/nomicon/phantom-data.md b/src/doc/nomicon/phantom-data.md
new file mode 100644
index 00000000000..0d7ec7f1617
--- /dev/null
+++ b/src/doc/nomicon/phantom-data.md
@@ -0,0 +1,87 @@
+% PhantomData
+
+When working with unsafe code, we can often end up in a situation where
+types or lifetimes are logically associated with a struct, but not actually
+part of a field. This most commonly occurs with lifetimes. For instance, the
+`Iter` for `&'a [T]` is (approximately) defined as follows:
+
+```rust,ignore
+struct Iter<'a, T: 'a> {
+    ptr: *const T,
+    end: *const T,
+}
+```
+
+However because `'a` is unused within the struct's body, it's *unbounded*.
+Because of the troubles this has historically caused, unbounded lifetimes and
+types are *forbidden* in struct definitions. Therefore we must somehow refer
+to these types in the body. Correctly doing this is necessary to have
+correct variance and drop checking.
+
+We do this using `PhantomData`, which is a special marker type. `PhantomData`
+consumes no space, but simulates a field of the given type for the purpose of
+static analysis. This was deemed to be less error-prone than explicitly telling
+the type-system the kind of variance that you want, while also providing other
+useful such as the information needed by drop check.
+
+Iter logically contains a bunch of `&'a T`s, so this is exactly what we tell
+the PhantomData to simulate:
+
+```
+use std::marker;
+
+struct Iter<'a, T: 'a> {
+    ptr: *const T,
+    end: *const T,
+    _marker: marker::PhantomData<&'a T>,
+}
+```
+
+and that's it. The lifetime will be bounded, and your iterator will be variant
+over `'a` and `T`. Everything Just Works.
+
+Another important example is Vec, which is (approximately) defined as follows:
+
+```
+struct Vec<T> {
+    data: *const T, // *const for variance!
+    len: usize,
+    cap: usize,
+}
+```
+
+Unlike the previous example it *appears* that everything is exactly as we
+want. Every generic argument to Vec shows up in the at least one field.
+Good to go!
+
+Nope.
+
+The drop checker will generously determine that Vec<T> does not own any values
+of type T. This will in turn make it conclude that it doesn't need to worry
+about Vec dropping any T's in its destructor for determining drop check
+soundness. This will in turn allow people to create unsoundness using
+Vec's destructor.
+
+In order to tell dropck that we *do* own values of type T, and therefore may
+drop some T's when *we* drop, we must add an extra PhantomData saying exactly
+that:
+
+```
+use std::marker;
+
+struct Vec<T> {
+    data: *const T, // *const for covariance!
+    len: usize,
+    cap: usize,
+    _marker: marker::PhantomData<T>,
+}
+```
+
+Raw pointers that own an allocation is such a pervasive pattern that the
+standard library made a utility for itself called `Unique<T>` which:
+
+* wraps a `*const T` for variance
+* includes a `PhantomData<T>`,
+* auto-derives Send/Sync as if T was contained
+* marks the pointer as NonZero for the null-pointer optimization
+
diff --git a/src/doc/nomicon/poisoning.md b/src/doc/nomicon/poisoning.md
new file mode 100644
index 00000000000..70de91af61f
--- /dev/null
+++ b/src/doc/nomicon/poisoning.md
@@ -0,0 +1,35 @@
+% Poisoning
+
+Although all unsafe code *must* ensure it has minimal exception safety, not all
+types ensure *maximal* exception safety. Even if the type does, your code may
+ascribe additional meaning to it. For instance, an integer is certainly
+exception-safe, but has no semantics on its own. It's possible that code that
+panics could fail to correctly update the integer, producing an inconsistent
+program state.
+
+This is *usually* fine, because anything that witnesses an exception is about
+to get destroyed. For instance, if you send a Vec to another thread and that
+thread panics, it doesn't matter if the Vec is in a weird state. It will be
+dropped and go away forever. However some types are especially good at smuggling
+values across the panic boundary.
+
+These types may choose to explicitly *poison* themselves if they witness a panic.
+Poisoning doesn't entail anything in particular. Generally it just means
+preventing normal usage from proceeding. The most notable example of this is the
+standard library's Mutex type. A Mutex will poison itself if one of its
+MutexGuards (the thing it returns when a lock is obtained) is dropped during a
+panic. Any future attempts to lock the Mutex will return an `Err` or panic.
+
+Mutex poisons not for true safety in the sense that Rust normally cares about. It
+poisons as a safety-guard against blindly using the data that comes out of a Mutex
+that has witnessed a panic while locked. The data in such a Mutex was likely in the
+middle of being modified, and as such may be in an inconsistent or incomplete state.
+It is important to note that one cannot violate memory safety with such a type
+if it is correctly written. After all, it must be minimally exception-safe!
+
+However if the Mutex contained, say, a BinaryHeap that does not actually have the
+heap property, it's unlikely that any code that uses it will do
+what the author intended. As such, the program should not proceed normally.
+Still, if you're double-plus-sure that you can do *something* with the value,
+the Mutex exposes a method to get the lock anyway. It *is* safe, after all.
+Just maybe nonsense.
diff --git a/src/doc/nomicon/races.md b/src/doc/nomicon/races.md
new file mode 100644
index 00000000000..3b47502ebfe
--- /dev/null
+++ b/src/doc/nomicon/races.md
@@ -0,0 +1,86 @@
+% Data Races and Race Conditions
+
+Safe Rust guarantees an absence of data races, which are defined as:
+
+* two or more threads concurrently accessing a location of memory
+* one of them is a write
+* one of them is unsynchronized
+
+A data race has Undefined Behaviour, and is therefore impossible to perform
+in Safe Rust. Data races are *mostly* prevented through rust's ownership system:
+it's impossible to alias a mutable reference, so it's impossible to perform a
+data race. Interior mutability makes this more complicated, which is largely why
+we have the Send and Sync traits (see below).
+
+**However Rust does not prevent general race conditions.**
+
+This is pretty fundamentally impossible, and probably honestly undesirable. Your
+hardware is racy, your OS is racy, the other programs on your computer are racy,
+and the world this all runs in is racy. Any system that could genuinely claim to
+prevent *all* race conditions would be pretty awful to use, if not just
+incorrect.
+
+So it's perfectly "fine" for a Safe Rust program to get deadlocked or do
+something incredibly stupid with incorrect synchronization. Obviously such a
+program isn't very good, but Rust can only hold your hand so far. Still, a
+race condition can't violate memory safety in a Rust program on
+its own. Only in conjunction with some other unsafe code can a race condition
+actually violate memory safety. For instance:
+
+```rust,no_run
+use std::thread;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Arc;
+
+let data = vec![1, 2, 3, 4];
+// Arc so that the memory the AtomicUsize is stored in still exists for
+// the other thread to increment, even if we completely finish executing
+// before it. Rust won't compile the program without it, because of the
+// lifetime requirements of thread::spawn!
+let idx = Arc::new(AtomicUsize::new(0));
+let other_idx = idx.clone();
+
+// `move` captures other_idx by-value, moving it into this thread
+thread::spawn(move || {
+    // It's ok to mutate idx because this value
+    // is an atomic, so it can't cause a Data Race.
+    other_idx.fetch_add(10, Ordering::SeqCst);
+});
+
+// Index with the value loaded from the atomic. This is safe because we
+// read the atomic memory only once, and then pass a copy of that value
+// to the Vec's indexing implementation. This indexing will be correctly
+// bounds checked, and there's no chance of the value getting changed
+// in the middle. However our program may panic if the thread we spawned
+// managed to increment before this ran. A race condition because correct
+// program execution (panicing is rarely correct) depends on order of
+// thread execution.
+println!("{}", data[idx.load(Ordering::SeqCst)]);
+```
+
+```rust,no_run
+use std::thread;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Arc;
+
+let data = vec![1, 2, 3, 4];
+
+let idx = Arc::new(AtomicUsize::new(0));
+let other_idx = idx.clone();
+
+// `move` captures other_idx by-value, moving it into this thread
+thread::spawn(move || {
+    // It's ok to mutate idx because this value
+    // is an atomic, so it can't cause a Data Race.
+    other_idx.fetch_add(10, Ordering::SeqCst);
+});
+
+if idx.load(Ordering::SeqCst) < data.len() {
+    unsafe {
+        // Incorrectly loading the idx after we did the bounds check.
+        // It could have changed. This is a race condition, *and dangerous*
+        // because we decided to do `get_unchecked`, which is `unsafe`.
+        println!("{}", data.get_unchecked(idx.load(Ordering::SeqCst)));
+    }
+}
+```
diff --git a/src/doc/nomicon/references.md b/src/doc/nomicon/references.md
new file mode 100644
index 00000000000..3d7369eca0f
--- /dev/null
+++ b/src/doc/nomicon/references.md
@@ -0,0 +1,177 @@
+% References
+
+This section gives a high-level view of the memory model that *all* Rust
+programs must satisfy to be correct. Safe code is statically verified
+to obey this model by the borrow checker. Unsafe code may go above
+and beyond the borrow checker while still satisfying this model. The borrow
+checker may also be extended to allow more programs to compile, as long as
+this more fundamental model is satisfied.
+
+There are two kinds of reference:
+
+* Shared reference: `&`
+* Mutable reference: `&mut`
+
+Which obey the following rules:
+
+* A reference cannot outlive its referent
+* A mutable reference cannot be aliased
+
+That's it. That's the whole model. Of course, we should probably define
+what *aliased* means. To define aliasing, we must define the notion of
+*paths* and *liveness*.
+
+
+**NOTE: The model that follows is generally agreed to be dubious and have
+issues. It's ok-ish as an intuitive model, but fails to capture the desired
+semantics. We leave this here to be able to use notions introduced here in later
+sections. This will be significantly changed in the future. TODO: do that.**
+
+
+# Paths
+
+If all Rust had were values (no pointers), then every value would be uniquely
+owned by a variable or composite structure. From this we naturally derive a
+*tree* of ownership. The stack itself is the root of the tree, with every
+variable as its direct children. Each variable's direct children would be their
+fields (if any), and so on.
+
+From this view, every value in Rust has a unique *path* in the tree of
+ownership. Of particular interest are *ancestors* and *descendants*: if `x` owns
+`y`, then `x` is an ancestor of `y`, and `y` is a descendant of `x`. Note
+that this is an inclusive relationship: `x` is a descendant and ancestor of
+itself.
+
+We can then define references as simply *names* for paths. When you create a
+reference, you're declaring that an ownership path exists to this address
+of memory.
+
+Tragically, plenty of data doesn't reside on the stack, and we must also
+accommodate this. Globals and thread-locals are simple enough to model as
+residing at the bottom of the stack (though we must be careful with mutable
+globals). Data on the heap poses a different problem.
+
+If all Rust had on the heap was data uniquely owned by a pointer on the stack,
+then we could just treat such a pointer as a struct that owns the value on the
+heap. Box, Vec, String, and HashMap, are examples of types which uniquely
+own data on the heap.
+
+Unfortunately, data on the heap is not *always* uniquely owned. Rc for instance
+introduces a notion of *shared* ownership. Shared ownership of a value means
+there is no unique path to it. A value with no unique path limits what we can do
+with it.
+
+In general, only shared references can be created to non-unique paths. However
+mechanisms which ensure mutual exclusion may establish One True Owner
+temporarily, establishing a unique path to that value (and therefore all
+its children). If this is done, the value may be mutated. In particular, a
+mutable reference can be taken.
+
+The most common way to establish such a path is through *interior mutability*,
+in contrast to the *inherited mutability* that everything in Rust normally uses.
+Cell, RefCell, Mutex, and RWLock are all examples of interior mutability types.
+These types provide exclusive access through runtime restrictions.
+
+An interesting case of this effect is Rc itself: if an Rc has refcount 1,
+then it is safe to mutate or even move its internals. Note however that the
+refcount itself uses interior mutability.
+
+In order to correctly communicate to the type system that a variable or field of
+a struct can have interior mutability, it must be wrapped in an UnsafeCell. This
+does not in itself make it safe to perform interior mutability operations on
+that value. You still must yourself ensure that mutual exclusion is upheld.
+
+
+
+
+# Liveness
+
+Note: Liveness is not the same thing as a *lifetime*, which will be explained
+in detail in the next section of this chapter.
+
+Roughly, a reference is *live* at some point in a program if it can be
+dereferenced. Shared references are always live unless they are literally
+unreachable (for instance, they reside in freed or leaked memory). Mutable
+references can be reachable but *not* live through the process of *reborrowing*.
+
+A mutable reference can be reborrowed to either a shared or mutable reference to
+one of its descendants. A reborrowed reference will only be live again once all
+reborrows derived from it expire. For instance, a mutable reference can be
+reborrowed to point to a field of its referent:
+
+```rust
+let x = &mut (1, 2);
+{
+    // reborrow x to a subfield
+    let y = &mut x.0;
+    // y is now live, but x isn't
+    *y = 3;
+}
+// y goes out of scope, so x is live again
+*x = (5, 7);
+```
+
+It is also possible to reborrow into *multiple* mutable references, as long as
+they are *disjoint*: no reference is an ancestor of another. Rust
+explicitly enables this to be done with disjoint struct fields, because
+disjointness can be statically proven:
+
+```rust
+let x = &mut (1, 2);
+{
+    // reborrow x to two disjoint subfields
+    let y = &mut x.0;
+    let z = &mut x.1;
+
+    // y and z are now live, but x isn't
+    *y = 3;
+    *z = 4;
+}
+// y and z go out of scope, so x is live again
+*x = (5, 7);
+```
+
+However it's often the case that Rust isn't sufficiently smart to prove that
+multiple borrows are disjoint. *This does not mean it is fundamentally illegal
+to make such a borrow*, just that Rust isn't as smart as you want.
+
+To simplify things, we can model variables as a fake type of reference: *owned*
+references. Owned references have much the same semantics as mutable references:
+they can be re-borrowed in a mutable or shared manner, which makes them no
+longer live. Live owned references have the unique property that they can be
+moved out of (though mutable references *can* be swapped out of). This power is
+only given to *live* owned references because moving its referent would of
+course invalidate all outstanding references prematurely.
+
+As a local lint against inappropriate mutation, only variables that are marked
+as `mut` can be borrowed mutably.
+
+It is interesting to note that Box behaves exactly like an owned reference. It
+can be moved out of, and Rust understands it sufficiently to reason about its
+paths like a normal variable.
+
+
+
+
+# Aliasing
+
+With liveness and paths defined, we can now properly define *aliasing*:
+
+**A mutable reference is aliased if there exists another live reference to one
+of its ancestors or descendants.**
+
+(If you prefer, you may also say the two live references alias *each other*.
+This has no semantic consequences, but is probably a more useful notion when
+verifying the soundness of a construct.)
+
+That's it. Super simple right? Except for the fact that it took us two pages to
+define all of the terms in that definition. You know: Super. Simple.
+
+Actually it's a bit more complicated than that. In addition to references, Rust
+has *raw pointers*: `*const T` and `*mut T`. Raw pointers have no inherent
+ownership or aliasing semantics. As a result, Rust makes absolutely no effort to
+track that they are used correctly, and they are wildly unsafe.
+
+**It is an open question to what degree raw pointers have alias semantics.
+However it is important for these definitions to be sound that the existence of
+a raw pointer does not imply some kind of live path.**
diff --git a/src/doc/nomicon/repr-rust.md b/src/doc/nomicon/repr-rust.md
new file mode 100644
index 00000000000..c8a372be767
--- /dev/null
+++ b/src/doc/nomicon/repr-rust.md
@@ -0,0 +1,152 @@
+% repr(Rust)
+
+First and foremost, all types have an alignment specified in bytes. The
+alignment of a type specifies what addresses are valid to store the value at. A
+value of alignment `n` must only be stored at an address that is a multiple of
+`n`. So alignment 2 means you must be stored at an even address, and 1 means
+that you can be stored anywhere. Alignment is at least 1, and always a power of
+2. Most primitives are generally aligned to their size, although this is
+platform-specific behaviour. In particular, on x86 `u64` and `f64` may be only
+aligned to 32 bits.
+
+A type's size must always be a multiple of its alignment. This ensures that an
+array of that type may always be indexed by offsetting by a multiple of its
+size. Note that the size and alignment of a type may not be known
+statically in the case of [dynamically sized types][dst].
+
+Rust gives you the following ways to lay out composite data:
+
+* structs (named product types)
+* tuples (anonymous product types)
+* arrays (homogeneous product types)
+* enums (named sum types -- tagged unions)
+
+An enum is said to be *C-like* if none of its variants have associated data.
+
+Composite structures will have an alignment equal to the maximum
+of their fields' alignment. Rust will consequently insert padding where
+necessary to ensure that all fields are properly aligned and that the overall
+type's size is a multiple of its alignment. For instance:
+
+```rust
+struct A {
+    a: u8,
+    b: u32,
+    c: u16,
+}
+```
+
+will be 32-bit aligned assuming these primitives are aligned to their size.
+It will therefore have a size that is a multiple of 32-bits. It will potentially
+*really* become:
+
+```rust
+struct A {
+    a: u8,
+    _pad1: [u8; 3], // to align `b`
+    b: u32,
+    c: u16,
+    _pad2: [u8; 2], // to make overall size multiple of 4
+}
+```
+
+There is *no indirection* for these types; all data is stored contiguously as
+you would expect in C. However with the exception of arrays (which are densely
+packed and in-order), the layout of data is not by default specified in Rust.
+Given the two following struct definitions:
+
+```rust
+struct A {
+    a: i32,
+    b: u64,
+}
+
+struct B {
+    x: i32,
+    b: u64,
+}
+```
+
+Rust *does* guarantee that two instances of A have their data laid out in
+exactly the same way. However Rust *does not* guarantee that an instance of A
+has the same field ordering or padding as an instance of B (in practice there's
+no particular reason why they wouldn't, other than that its not currently
+guaranteed).
+
+With A and B as written, this is basically nonsensical, but several other
+features of Rust make it desirable for the language to play with data layout in
+complex ways.
+
+For instance, consider this struct:
+
+```rust
+struct Foo<T, U> {
+    count: u16,
+    data1: T,
+    data2: U,
+}
+```
+
+Now consider the monomorphizations of `Foo<u32, u16>` and `Foo<u16, u32>`. If
+Rust lays out the fields in the order specified, we expect it to pad the
+values in the struct to satisfy their alignment requirements. So if Rust
+didn't reorder fields, we would expect it to produce the following:
+
+```rust,ignore
+struct Foo<u16, u32> {
+    count: u16,
+    data1: u16,
+    data2: u32,
+}
+
+struct Foo<u32, u16> {
+    count: u16,
+    _pad1: u16,
+    data1: u32,
+    data2: u16,
+    _pad2: u16,
+}
+```
+
+The latter case quite simply wastes space. An optimal use of space therefore
+requires different monomorphizations to have *different field orderings*.
+
+**Note: this is a hypothetical optimization that is not yet implemented in Rust
+1.0**
+
+Enums make this consideration even more complicated. Naively, an enum such as:
+
+```rust
+enum Foo {
+    A(u32),
+    B(u64),
+    C(u8),
+}
+```
+
+would be laid out as:
+
+```rust
+struct FooRepr {
+    data: u64, // this is either a u64, u32, or u8 based on `tag`
+    tag: u8,   // 0 = A, 1 = B, 2 = C
+}
+```
+
+And indeed this is approximately how it would be laid out in general
+(modulo the size and position of `tag`). However there are several cases where
+such a representation is inefficient. The classic case of this is Rust's
+"null pointer optimization". Given a pointer that is known to not be null
+(e.g. `&u32`), an enum can *store* a discriminant bit *inside* the pointer
+by using null as a special value. The net result is that
+`size_of::<Option<&T>>() == size_of::<&T>()`
+
+There are many types in Rust that are, or contain, "not null" pointers such as
+`Box<T>`, `Vec<T>`, `String`, `&T`, and `&mut T`. Similarly, one can imagine
+nested enums pooling their tags into a single discriminant, as they are by
+definition known to have a limited range of valid values. In principle enums can
+use fairly elaborate algorithms to cache bits throughout nested types with
+special constrained representations. As such it is *especially* desirable that
+we leave enum layout unspecified today.
+
+[dst]: exotic-sizes.html#dynamically-sized-types-(dsts)
diff --git a/src/doc/nomicon/safe-unsafe-meaning.md b/src/doc/nomicon/safe-unsafe-meaning.md
new file mode 100644
index 00000000000..2f15b7050e3
--- /dev/null
+++ b/src/doc/nomicon/safe-unsafe-meaning.md
@@ -0,0 +1,150 @@
+% How Safe and Unsafe Interact
+
+So what's the relationship between Safe and Unsafe Rust? How do they interact?
+
+Rust models the separation between Safe and Unsafe Rust with the `unsafe`
+keyword, which can be thought as a sort of *foreign function interface* (FFI)
+between Safe and Unsafe Rust. This is the magic behind why we can say Safe Rust
+is a safe language: all the scary unsafe bits are relegated exclusively to FFI
+*just like every other safe language*.
+
+However because one language is a subset of the other, the two can be cleanly
+intermixed as long as the boundary between Safe and Unsafe Rust is denoted with
+the `unsafe` keyword. No need to write headers, initialize runtimes, or any of
+that other FFI boiler-plate.
+
+There are several places `unsafe` can appear in Rust today, which can largely be
+grouped into two categories:
+
+* There are unchecked contracts here. To declare you understand this, I require
+you to write `unsafe` elsewhere:
+    * On functions, `unsafe` is declaring the function to be unsafe to call.
+      Users of the function must check the documentation to determine what this
+      means, and then have to write `unsafe` somewhere to identify that they're
+      aware of the danger.
+    * On trait declarations, `unsafe` is declaring that *implementing* the trait
+      is an unsafe operation, as it has contracts that other unsafe code is free
+      to trust blindly. (More on this below.)
+
+* I am declaring that I have, to the best of my knowledge, adhered to the
+unchecked contracts:
+    * On trait implementations, `unsafe` is declaring that the contract of the
+      `unsafe` trait has been upheld.
+    * On blocks, `unsafe` is declaring any unsafety from an unsafe
+      operation within to be handled, and therefore the parent function is safe.
+
+There is also `#[unsafe_no_drop_flag]`, which is a special case that exists for
+historical reasons and is in the process of being phased out. See the section on
+[drop flags][] for details.
+
+Some examples of unsafe functions:
+
+* `slice::get_unchecked` will perform unchecked indexing, allowing memory
+  safety to be freely violated.
+* `ptr::offset` is an intrinsic that invokes Undefined Behaviour if it is
+  not "in bounds" as defined by LLVM.
+* `mem::transmute` reinterprets some value as having the given type,
+  bypassing type safety in arbitrary ways. (see [conversions][] for details)
+* All FFI functions are `unsafe` because they can do arbitrary things.
+  C being an obvious culprit, but generally any language can do something
+  that Rust isn't happy about.
+
+As of Rust 1.0 there are exactly two unsafe traits:
+
+* `Send` is a marker trait (it has no actual API) that promises implementors
+  are safe to send (move) to another thread.
+* `Sync` is a marker trait that promises that threads can safely share
+  implementors through a shared reference.
+
+The need for unsafe traits boils down to the fundamental property of safe code:
+
+**No matter how completely awful Safe code is, it can't cause Undefined
+Behaviour.**
+
+This means that Unsafe Rust, **the royal vanguard of Undefined Behaviour**, has to be
+*super paranoid* about generic safe code. To be clear, Unsafe Rust is totally free to trust
+specific safe code. Anything else would degenerate into infinite spirals of
+paranoid despair. In particular it's generally regarded as ok to trust the standard library
+to be correct. `std` is effectively an extension of the language, and you
+really just have to trust the language. If `std` fails to uphold the
+guarantees it declares, then it's basically a language bug.
+
+That said, it would be best to minimize *needlessly* relying on properties of
+concrete safe code. Bugs happen! Of course, I must reinforce that this is only
+a concern for Unsafe code. Safe code can blindly trust anyone and everyone
+as far as basic memory-safety is concerned.
+
+On the other hand, safe traits are free to declare arbitrary contracts, but because
+implementing them is safe, unsafe code can't trust those contracts to actually
+be upheld. This is different from the concrete case because *anyone* can
+randomly implement the interface. There is something fundamentally different
+about trusting a particular piece of code to be correct, and trusting *all the
+code that will ever be written* to be correct.
+
+For instance Rust has `PartialOrd` and `Ord` traits to try to differentiate
+between types which can "just" be compared, and those that actually implement a
+total ordering. Pretty much every API that wants to work with data that can be
+compared wants Ord data. For instance, a sorted map like BTreeMap
+*doesn't even make sense* for partially ordered types. If you claim to implement
+Ord for a type, but don't actually provide a proper total ordering, BTreeMap will
+get *really confused* and start making a total mess of itself. Data that is
+inserted may be impossible to find!
+
+But that's okay. BTreeMap is safe, so it guarantees that even if you give it a
+completely garbage Ord implementation, it will still do something *safe*. You
+won't start reading uninitialized or unallocated memory. In fact, BTreeMap
+manages to not actually lose any of your data. When the map is dropped, all the
+destructors will be successfully called! Hooray!
+
+However BTreeMap is implemented using a modest spoonful of Unsafe Rust (most collections
+are). That means that it's not necessarily *trivially true* that a bad Ord
+implementation will make BTreeMap behave safely. BTreeMap must be sure not to rely
+on Ord *where safety is at stake*. Ord is provided by safe code, and safety is not
+safe code's responsibility to uphold.
+
+But wouldn't it be grand if there was some way for Unsafe to trust some trait
+contracts *somewhere*? This is the problem that unsafe traits tackle: by marking
+*the trait itself* as unsafe to implement, unsafe code can trust the implementation
+to uphold the trait's contract. Although the trait implementation may be
+incorrect in arbitrary other ways.
+
+For instance, given a hypothetical UnsafeOrd trait, this is technically a valid
+implementation:
+
+```rust
+# use std::cmp::Ordering;
+# struct MyType;
+# unsafe trait UnsafeOrd { fn cmp(&self, other: &Self) -> Ordering; }
+unsafe impl UnsafeOrd for MyType {
+    fn cmp(&self, other: &Self) -> Ordering {
+        Ordering::Equal
+    }
+}
+```
+
+But it's probably not the implementation you want.
+
+Rust has traditionally avoided making traits unsafe because it makes Unsafe
+pervasive, which is not desirable. Send and Sync are unsafe is because thread
+safety is a *fundamental property* that unsafe code cannot possibly hope to defend
+against in the same way it would defend against a bad Ord implementation. The
+only way to possibly defend against thread-unsafety would be to *not use
+threading at all*. Making every load and store atomic isn't even sufficient,
+because it's possible for complex invariants to exist between disjoint locations
+in memory. For instance, the pointer and capacity of a Vec must be in sync.
+
+Even concurrent paradigms that are traditionally regarded as Totally Safe like
+message passing implicitly rely on some notion of thread safety -- are you
+really message-passing if you pass a pointer? Send and Sync therefore require
+some fundamental level of trust that Safe code can't provide, so they must be
+unsafe to implement. To help obviate the pervasive unsafety that this would
+introduce, Send (resp. Sync) is automatically derived for all types composed only
+of Send (resp. Sync) values. 99% of types are Send and Sync, and 99% of those
+never actually say it (the remaining 1% is overwhelmingly synchronization
+primitives).
+
+
+
+
+[drop flags]: drop-flags.html
+[conversions]: conversions.html
diff --git a/src/doc/nomicon/send-and-sync.md b/src/doc/nomicon/send-and-sync.md
new file mode 100644
index 00000000000..334d5c9dd55
--- /dev/null
+++ b/src/doc/nomicon/send-and-sync.md
@@ -0,0 +1,80 @@
+% Send and Sync
+
+Not everything obeys inherited mutability, though. Some types allow you to
+multiply alias a location in memory while mutating it. Unless these types use
+synchronization to manage this access, they are absolutely not thread safe. Rust
+captures this with through the `Send` and `Sync` traits.
+
+* A type is Send if it is safe to send it to another thread.
+* A type is Sync if it is safe to share between threads (`&T` is Send).
+
+Send and Sync are fundamental to Rust's concurrency story. As such, a
+substantial amount of special tooling exists to make them work right. First and
+foremost, they're [unsafe traits][]. This means that they are unsafe to
+implement, and other unsafe code can  that they are correctly
+implemented. Since they're *marker traits* (they have no associated items like
+methods), correctly implemented simply means that they have the intrinsic
+properties an implementor should have. Incorrectly implementing Send or Sync can
+cause Undefined Behaviour.
+
+Send and Sync are also automatically derived traits. This means that, unlike
+every other trait, if a type is composed entirely of Send or Sync types, then it
+is Send or Sync. Almost all primitives are Send and Sync, and as a consequence
+pretty much all types you'll ever interact with are Send and Sync.
+
+Major exceptions include:
+
+* raw pointers are neither Send nor Sync (because they have no safety guards).
+* `UnsafeCell` isn't Sync (and therefore `Cell` and `RefCell` aren't).
+* `Rc` isn't Send or Sync (because the refcount is shared and unsynchronized).
+
+`Rc` and `UnsafeCell` are very fundamentally not thread-safe: they enable
+unsynchronized shared mutable state. However raw pointers are, strictly
+speaking, marked as thread-unsafe as more of a *lint*. Doing anything useful
+with a raw pointer requires dereferencing it, which is already unsafe. In that
+sense, one could argue that it would be "fine" for them to be marked as thread
+safe.
+
+However it's important that they aren't thread safe to prevent types that
+contain them from being automatically marked as thread safe. These types have
+non-trivial untracked ownership, and it's unlikely that their author was
+necessarily thinking hard about thread safety. In the case of Rc, we have a nice
+example of a type that contains a `*mut` that is definitely not thread safe.
+
+Types that aren't automatically derived can simply implement them if desired:
+
+```rust
+struct MyBox(*mut u8);
+
+unsafe impl Send for MyBox {}
+unsafe impl Sync for MyBox {}
+```
+
+In the *incredibly rare* case that a type is inappropriately automatically
+derived to be Send or Sync, then one can also unimplement Send and Sync:
+
+```rust
+#![feature(optin_builtin_traits)]
+
+// I have some magic semantics for some synchronization primitive!
+struct SpecialThreadToken(u8);
+
+impl !Send for SpecialThreadToken {}
+impl !Sync for SpecialThreadToken {}
+```
+
+Note that *in and of itself* it is impossible to incorrectly derive Send and
+Sync. Only types that are ascribed special meaning by other unsafe code can
+possible cause trouble by being incorrectly Send or Sync.
+
+Most uses of raw pointers should be encapsulated behind a sufficient abstraction
+that Send and Sync can be derived. For instance all of Rust's standard
+collections are Send and Sync (when they contain Send and Sync types) in spite
+of their pervasive use of raw pointers to manage allocations and complex ownership.
+Similarly, most iterators into these collections are Send and Sync because they
+largely behave like an `&` or `&mut` into the collection.
+
+TODO: better explain what can or can't be Send or Sync. Sufficient to appeal
+only to data races?
+
+[unsafe traits]: safe-unsafe-meaning.html
diff --git a/src/doc/nomicon/subtyping.md b/src/doc/nomicon/subtyping.md
new file mode 100644
index 00000000000..3c57297f323
--- /dev/null
+++ b/src/doc/nomicon/subtyping.md
@@ -0,0 +1,212 @@
+% Subtyping and Variance
+
+Although Rust doesn't have any notion of structural inheritance, it *does*
+include subtyping. In Rust, subtyping derives entirely from lifetimes. Since
+lifetimes are scopes, we can partially order them based on the *contains*
+(outlives) relationship. We can even express this as a generic bound.
+
+Subtyping on lifetimes is in terms of that relationship: if `'a: 'b` ("a contains
+b" or "a outlives b"), then `'a` is a subtype of `'b`. This is a large source of
+confusion, because it seems intuitively backwards to many: the bigger scope is a
+*subtype* of the smaller scope.
+
+This does in fact make sense, though. The intuitive reason for this is that if
+you expect an `&'a u8`, then it's totally fine for me to hand you an `&'static
+u8`, in the same way that if you expect an Animal in Java, it's totally fine for
+me to hand you a Cat. Cats are just Animals *and more*, just as `'static` is
+just `'a` *and more*.
+
+(Note, the subtyping relationship and typed-ness of lifetimes is a fairly
+arbitrary construct that some disagree with. However it simplifies our analysis
+to treat lifetimes and types uniformly.)
+
+Higher-ranked lifetimes are also subtypes of every concrete lifetime. This is
+because taking an arbitrary lifetime is strictly more general than taking a
+specific one.
+
+
+
+# Variance
+
+Variance is where things get a bit complicated.
+
+Variance is a property that *type constructors* have with respect to their
+arguments. A type constructor in Rust is a generic type with unbound arguments.
+For instance `Vec` is a type constructor that takes a `T` and returns a
+`Vec<T>`. `&` and `&mut` are type constructors that take two inputs: a
+lifetime, and a type to point to.
+
+A type constructor's *variance* is how the subtyping of its inputs affects the
+subtyping of its outputs. There are two kinds of variance in Rust:
+
+* F is *variant* over `T` if `T` being a subtype of `U` implies
+  `F<T>` is a subtype of `F<U>` (subtyping "passes through")
+* F is *invariant* over `T` otherwise (no subtyping relation can be derived)
+
+(For those of you who are familiar with variance from other languages, what we
+refer to as "just" variance is in fact *covariance*. Rust does not have
+contravariance. Historically Rust did have some contravariance but it was
+scrapped due to poor interactions with other features. If you experience
+contravariance in Rust call your local compiler developer for medical advice.)
+
+Some important variances:
+
+* `&'a T` is variant over `'a` and `T` (as is `*const T` by metaphor)
+* `&'a mut T` is variant with over `'a` but invariant over `T`
+* `Fn(T) -> U` is invariant over `T`, but variant over `U`
+* `Box`, `Vec`, and all other collections are variant over the types of
+  their contents
+* `UnsafeCell<T>`, `Cell<T>`, `RefCell<T>`, `Mutex<T>` and all other
+  interior mutability types are invariant over T (as is `*mut T` by metaphor)
+
+To understand why these variances are correct and desirable, we will consider
+several examples.
+
+
+We have already covered why `&'a T` should be variant over `'a` when
+introducing subtyping: it's desirable to be able to pass longer-lived things
+where shorter-lived things are needed.
+
+Similar reasoning applies to why it should be variant over T. It is reasonable
+to be able to pass `&&'static str` where an `&&'a str` is expected. The
+additional level of indirection does not change the desire to be able to pass
+longer lived things where shorted lived things are expected.
+
+However this logic doesn't apply to `&mut`. To see why `&mut` should
+be invariant over T, consider the following code:
+
+```rust,ignore
+fn overwrite<T: Copy>(input: &mut T, new: &mut T) {
+    *input = *new;
+}
+
+fn main() {
+    let mut forever_str: &'static str = "hello";
+    {
+        let string = String::from("world");
+        overwrite(&mut forever_str, &mut &*string);
+    }
+    // Oops, printing free'd memory
+    println!("{}", forever_str);
+}
+```
+
+The signature of `overwrite` is clearly valid: it takes mutable references to
+two values of the same type, and overwrites one with the other. If `&mut T` was
+variant over T, then `&mut &'a str` would be a subtype of `&mut &'static str`,
+since `&'a str` is a subtype of `&'static str`. Therefore the lifetime of
+`forever_str` would successfully be "shrunk" down to the shorter lifetime of
+`string`, and `overwrite` would be called successfully. `string` would
+subsequently be dropped, and `forever_str` would point to freed memory when we
+print it! Therefore `&mut` should be invariant.
+
+This is the general theme of variance vs invariance: if variance would allow you
+to store a short-lived value into a longer-lived slot, then you must be
+invariant.
+
+However it *is* sound for `&'a mut T` to be variant over `'a`. The key difference
+between `'a` and T is that `'a` is a property of the reference itself,
+while T is something the reference is borrowing. If you change T's type, then
+the source still remembers the original type. However if you change the
+lifetime's type, no one but the reference knows this information, so it's fine.
+Put another way: `&'a mut T` owns `'a`, but only *borrows* T.
+
+`Box` and `Vec` are interesting cases because they're variant, but you can
+definitely store values in them! This is where Rust gets really clever: it's
+fine for them to be variant because you can only store values
+in them *via a mutable reference*! The mutable reference makes the whole type
+invariant, and therefore prevents you from smuggling a short-lived type into
+them.
+
+Being variant allows `Box` and `Vec` to be weakened when shared
+immutably. So you can pass a `&Box<&'static str>` where a `&Box<&'a str>` is
+expected.
+
+However what should happen when passing *by-value* is less obvious. It turns out
+that, yes, you can use subtyping when passing by-value. That is, this works:
+
+```rust
+fn get_box<'a>(str: &'a str) -> Box<&'a str> {
+    // string literals are `&'static str`s
+    Box::new("hello")
+}
+```
+
+Weakening when you pass by-value is fine because there's no one else who
+"remembers" the old lifetime in the Box. The reason a variant `&mut` was
+trouble was because there's always someone else who remembers the original
+subtype: the actual owner.
+
+The invariance of the cell types can be seen as follows: `&` is like an `&mut`
+for a cell, because you can still store values in them through an `&`. Therefore
+cells must be invariant to avoid lifetime smuggling.
+
+`Fn` is the most subtle case because it has mixed variance. To see why
+`Fn(T) -> U` should be invariant over T, consider the following function
+signature:
+
+```rust,ignore
+// 'a is derived from some parent scope
+fn foo(&'a str) -> usize;
+```
+
+This signature claims that it can handle any `&str` that lives at least as
+long as `'a`. Now if this signature was variant over `&'a str`, that
+would mean
+
+```rust,ignore
+fn foo(&'static str) -> usize;
+```
+
+could be provided in its place, as it would be a subtype. However this function
+has a stronger requirement: it says that it can only handle `&'static str`s,
+and nothing else. Giving `&'a str`s to it would be unsound, as it's free to
+assume that what it's given lives forever. Therefore functions are not variant
+over their arguments.
+
+To see why `Fn(T) -> U` should be variant over U, consider the following
+function signature:
+
+```rust,ignore
+// 'a is derived from some parent scope
+fn foo(usize) -> &'a str;
+```
+
+This signature claims that it will return something that outlives `'a`. It is
+therefore completely reasonable to provide
+
+```rust,ignore
+fn foo(usize) -> &'static str;
+```
+
+in its place. Therefore functions are variant over their return type.
+
+`*const` has the exact same semantics as `&`, so variance follows. `*mut` on the
+other hand can dereference to an `&mut` whether shared or not, so it is marked
+as invariant just like cells.
+
+This is all well and good for the types the standard library provides, but
+how is variance determined for type that *you* define? A struct, informally
+speaking, inherits the variance of its fields. If a struct `Foo`
+has a generic argument `A` that is used in a field `a`, then Foo's variance
+over `A` is exactly `a`'s variance. However this is complicated if `A` is used
+in multiple fields.
+
+* If all uses of A are variant, then Foo is variant over A
+* Otherwise, Foo is invariant over A
+
+```rust
+use std::cell::Cell;
+
+struct Foo<'a, 'b, A: 'a, B: 'b, C, D, E, F, G, H> {
+    a: &'a A,     // variant over 'a and A
+    b: &'b mut B, // invariant over 'b and B
+    c: *const C,  // variant over C
+    d: *mut D,    // invariant over D
+    e: Vec<E>,    // variant over E
+    f: Cell<F>,   // invariant over F
+    g: G,         // variant over G
+    h1: H,        // would also be variant over H except...
+    h2: Cell<H>,  // invariant over H, because invariance wins
+}
+```
diff --git a/src/doc/nomicon/transmutes.md b/src/doc/nomicon/transmutes.md
new file mode 100644
index 00000000000..f19dda0d8b8
--- /dev/null
+++ b/src/doc/nomicon/transmutes.md
@@ -0,0 +1,35 @@
+% Transmutes
+
+Get out of our way type system! We're going to reinterpret these bits or die
+trying! Even though this book is all about doing things that are unsafe, I
+really can't emphasize that you should deeply think about finding Another Way
+than the operations covered in this section. This is really, truly, the most
+horribly unsafe thing you can do in Rust. The railguards here are dental floss.
+
+`mem::transmute<T, U>` takes a value of type `T` and reinterprets it to have
+type `U`. The only restriction is that the `T` and `U` are verified to have the
+same size. The ways to cause Undefined Behaviour with this are mind boggling.
+
+* First and foremost, creating an instance of *any* type with an invalid state
+  is going to cause arbitrary chaos that can't really be predicted.
+* Transmute has an overloaded return type. If you do not specify the return type
+  it may produce a surprising type to satisfy inference.
+* Making a primitive with an invalid value is UB
+* Transmuting between non-repr(C) types is UB
+* Transmuting an & to &mut is UB
+    * Transmuting an & to &mut is *always* UB
+    * No you can't do it
+    * No you're not special
+* Transmuting to a reference without an explicitly provided lifetime
+  produces an [unbounded lifetime][]
+
+`mem::transmute_copy<T, U>` somehow manages to be *even more* wildly unsafe than
+this. It copies `size_of<U>` bytes out of an `&T` and interprets them as a `U`.
+The size check that `mem::transmute` has is gone (as it may be valid to copy
+out a prefix), though it is Undefined Behaviour for `U` to be larger than `T`.
+
+Also of course you can get most of the functionality of these functions using
+pointer casts.
+
+
+[unbounded lifetime]: unbounded-lifetimes.html
diff --git a/src/doc/nomicon/unbounded-lifetimes.md b/src/doc/nomicon/unbounded-lifetimes.md
new file mode 100644
index 00000000000..b540ab4ed5d
--- /dev/null
+++ b/src/doc/nomicon/unbounded-lifetimes.md
@@ -0,0 +1,37 @@
+% Unbounded Lifetimes
+
+Unsafe code can often end up producing references or lifetimes out of thin air.
+Such lifetimes come into the world as *unbounded*. The most common source of this
+is derefencing a raw pointer, which produces a reference with an unbounded lifetime.
+Such a lifetime becomes as big as context demands. This is in fact more powerful
+than simply becoming `'static`, because for instance `&'static &'a T`
+will fail to typecheck, but the unbound lifetime will perfectly mold into
+`&'a &'a T` as needed. However for most intents and purposes, such an unbounded
+lifetime can be regarded as `'static`.
+
+Almost no reference is `'static`, so this is probably wrong. `transmute` and
+`transmute_copy` are the two other primary offenders. One should endeavour to
+bound an unbounded lifetime as quick as possible, especially across function
+boundaries.
+
+Given a function, any output lifetimes that don't derive from inputs are
+unbounded. For instance:
+
+```rust,ignore
+fn get_str<'a>() -> &'a str;
+```
+
+will produce an `&str` with an unbounded lifetime. The easiest way to avoid
+unbounded lifetimes is to use lifetime elision at the function boundary.
+If an output lifetime is elided, then it *must* be bounded by an input lifetime.
+Of course it might be bounded by the *wrong* lifetime, but this will usually
+just cause a compiler error, rather than allow memory safety to be trivially
+violated.
+
+Within a function, bounding lifetimes is more error-prone. The safest and easiest
+way to bound a lifetime is to return it from a function with a bound lifetime.
+However if this is unacceptable, the reference can be placed in a location with
+a specific lifetime. Unfortunately it's impossible to name all lifetimes involved
+in a function. To get around this, you can in principle use `copy_lifetime`, though
+these are unstable due to their awkward nature and questionable utility.
+
diff --git a/src/doc/nomicon/unchecked-uninit.md b/src/doc/nomicon/unchecked-uninit.md
new file mode 100644
index 00000000000..da9fb294a1e
--- /dev/null
+++ b/src/doc/nomicon/unchecked-uninit.md
@@ -0,0 +1,85 @@
+% Unchecked Uninitialized Memory
+
+One interesting exception to this rule is working with arrays. Safe Rust doesn't
+permit you to partially initialize an array. When you initialize an array, you
+can either set every value to the same thing with `let x = [val; N]`, or you can
+specify each member individually with `let x = [val1, val2, val3]`.
+Unfortunately this is pretty rigid, especially if you need to initialize your
+array in a more incremental or dynamic way.
+
+Unsafe Rust gives us a powerful tool to handle this problem:
+`mem::uninitialized`. This function pretends to return a value when really
+it does nothing at all. Using it, we can convince Rust that we have initialized
+a variable, allowing us to do trickier things with conditional and incremental
+initialization.
+
+Unfortunately, this opens us up to all kinds of problems. Assignment has a
+different meaning to Rust based on whether it believes that a variable is
+initialized or not. If it's believed uninitialized, then Rust will semantically
+just memcopy the bits over the uninitialized ones, and do nothing else. However
+if Rust believes a value to be initialized, it will try to `Drop` the old value!
+Since we've tricked Rust into believing that the value is initialized, we can no
+longer safely use normal assignment.
+
+This is also a problem if you're working with a raw system allocator, which
+returns a pointer to uninitialized memory.
+
+To handle this, we must use the `ptr` module. In particular, it provides
+three functions that allow us to assign bytes to a location in memory without
+dropping the old value: `write`, `copy`, and `copy_nonoverlapping`.
+
+* `ptr::write(ptr, val)` takes a `val` and moves it into the address pointed
+  to by `ptr`.
+* `ptr::copy(src, dest, count)` copies the bits that `count` T's would occupy
+  from src to dest. (this is equivalent to memmove -- note that the argument
+  order is reversed!)
+* `ptr::copy_nonoverlapping(src, dest, count)` does what `copy` does, but a
+  little faster on the assumption that the two ranges of memory don't overlap.
+  (this is equivalent to memcpy -- note that the argument order is reversed!)
+
+It should go without saying that these functions, if misused, will cause serious
+havoc or just straight up Undefined Behaviour. The only things that these
+functions *themselves* require is that the locations you want to read and write
+are allocated. However the ways writing arbitrary bits to arbitrary
+locations of memory can break things are basically uncountable!
+
+Putting this all together, we get the following:
+
+```rust
+use std::mem;
+use std::ptr;
+
+// size of the array is hard-coded but easy to change. This means we can't
+// use [a, b, c] syntax to initialize the array, though!
+const SIZE: usize = 10;
+
+let mut x: [Box<u32>; SIZE];
+
+unsafe {
+	// convince Rust that x is Totally Initialized
+	x = mem::uninitialized();
+	for i in 0..SIZE {
+		// very carefully overwrite each index without reading it
+		// NOTE: exception safety is not a concern; Box can't panic
+		ptr::write(&mut x[i], Box::new(i as u32));
+	}
+}
+
+println!("{:?}", x);
+```
+
+It's worth noting that you don't need to worry about `ptr::write`-style
+shenanigans with types which don't implement `Drop` or contain `Drop` types,
+because Rust knows not to try to drop them. Similarly you should be able to
+assign to fields of partially initialized structs directly if those fields don't
+contain any `Drop` types.
+
+However when working with uninitialized memory you need to be ever-vigilant for
+Rust trying to drop values you make like this before they're fully initialized.
+Every control path through that variable's scope must initialize the value
+before it ends, if has a destructor.
+*[This includes code panicking](unwinding.html)*.
+
+And that's about it for working with uninitialized memory! Basically nothing
+anywhere expects to be handed uninitialized memory, so if you're going to pass
+it around at all, be sure to be *really* careful.
diff --git a/src/doc/nomicon/uninitialized.md b/src/doc/nomicon/uninitialized.md
new file mode 100644
index 00000000000..915ea860291
--- /dev/null
+++ b/src/doc/nomicon/uninitialized.md
@@ -0,0 +1,10 @@
+% Working With Uninitialized Memory
+
+All runtime-allocated memory in a Rust program begins its life as
+*uninitialized*. In this state the value of the memory is an indeterminate pile
+of bits that may or may not even reflect a valid state for the type that is
+supposed to inhabit that location of memory. Attempting to interpret this memory
+as a value of *any* type will cause Undefined Behaviour. Do Not Do This.
+
+Rust provides mechanisms to work with uninitialized memory in checked (safe) and
+unchecked (unsafe) ways.
\ No newline at end of file
diff --git a/src/doc/nomicon/unwinding.md b/src/doc/nomicon/unwinding.md
new file mode 100644
index 00000000000..3ad95dde39d
--- /dev/null
+++ b/src/doc/nomicon/unwinding.md
@@ -0,0 +1,49 @@
+% Unwinding
+
+Rust has a *tiered* error-handling scheme:
+
+* If something might reasonably be absent, Option is used.
+* If something goes wrong and can reasonably be handled, Result is used.
+* If something goes wrong and cannot reasonably be handled, the thread panics.
+* If something catastrophic happens, the program aborts.
+
+Option and Result are overwhelmingly preferred in most situations, especially
+since they can be promoted into a panic or abort at the API user's discretion.
+Panics cause the thread to halt normal execution and unwind its stack, calling
+destructors as if every function instantly returned.
+
+As of 1.0, Rust is of two minds when it comes to panics. In the long-long-ago,
+Rust was much more like Erlang. Like Erlang, Rust had lightweight tasks,
+and tasks were intended to kill themselves with a panic when they reached an
+untenable state. Unlike an exception in Java or C++, a panic could not be
+caught at any time. Panics could only be caught by the owner of the task, at which
+point they had to be handled or *that* task would itself panic.
+
+Unwinding was important to this story because if a task's
+destructors weren't called, it would cause memory and other system resources to
+leak. Since tasks were expected to die during normal execution, this would make
+Rust very poor for long-running systems!
+
+As the Rust we know today came to be, this style of programming grew out of
+fashion in the push for less-and-less abstraction. Light-weight tasks were
+killed in the name of heavy-weight OS threads. Still, on stable Rust as of 1.0
+panics can only be caught by the parent thread. This means catching a panic
+requires spinning up an entire OS thread! This unfortunately stands in conflict
+to Rust's philosophy of zero-cost abstractions.
+
+There is an unstable API called `catch_panic` that enables catching a panic
+without spawning a thread. Still, we would encourage you to only do this
+sparingly. In particular, Rust's current unwinding implementation is heavily
+optimized for the "doesn't unwind" case. If a program doesn't unwind, there
+should be no runtime cost for the program being *ready* to unwind. As a
+consequence, actually unwinding will be more expensive than in e.g. Java.
+Don't build your programs to unwind under normal circumstances. Ideally, you
+should only panic for programming errors or *extreme* problems.
+
+Rust's unwinding strategy is not specified to be fundamentally compatible
+with any other language's unwinding. As such, unwinding into Rust from another
+language, or unwinding into another language from Rust is Undefined Behaviour.
+You must *absolutely* catch any panics at the FFI boundary! What you do at that
+point is up to you, but *something* must be done. If you fail to do this,
+at best, your application will crash and burn. At worst, your application *won't*
+crash and burn, and will proceed with completely clobbered state.
diff --git a/src/doc/nomicon/vec-alloc.md b/src/doc/nomicon/vec-alloc.md
new file mode 100644
index 00000000000..fc7feba2356
--- /dev/null
+++ b/src/doc/nomicon/vec-alloc.md
@@ -0,0 +1,222 @@
+% Allocating Memory
+
+Using Unique throws a wrench in an important feature of Vec (and indeed all of
+the std collections): an empty Vec doesn't actually allocate at all. So if we
+can't allocate, but also can't put a null pointer in `ptr`, what do we do in
+`Vec::new`? Well, we just put some other garbage in there!
+
+This is perfectly fine because we already have `cap == 0` as our sentinel for no
+allocation. We don't even need to handle it specially in almost any code because
+we usually need to check if `cap > len` or `len > 0` anyway. The traditional
+Rust value to put here is `0x01`. The standard library actually exposes this
+as `std::rt::heap::EMPTY`. There are quite a few places where we'll
+want to use `heap::EMPTY` because there's no real allocation to talk about but
+`null` would make the compiler do bad things.
+
+All of the `heap` API is totally unstable under the `heap_api` feature, though.
+We could trivially define `heap::EMPTY` ourselves, but we'll want the rest of
+the `heap` API anyway, so let's just get that dependency over with.
+
+So:
+
+```rust,ignore
+#![feature(heap_api)]
+
+use std::rt::heap::EMPTY;
+use std::mem;
+
+impl<T> Vec<T> {
+    fn new() -> Self {
+        assert!(mem::size_of::<T>() != 0, "We're not ready to handle ZSTs");
+        unsafe {
+            // need to cast EMPTY to the actual ptr type we want, let
+            // inference handle it.
+            Vec { ptr: Unique::new(heap::EMPTY as *mut _), len: 0, cap: 0 }
+        }
+    }
+}
+```
+
+I slipped in that assert there because zero-sized types will require some
+special handling throughout our code, and I want to defer the issue for now.
+Without this assert, some of our early drafts will do some Very Bad Things.
+
+Next we need to figure out what to actually do when we *do* want space. For
+that, we'll need to use the rest of the heap APIs. These basically allow us to
+talk directly to Rust's allocator (jemalloc by default).
+
+We'll also need a way to handle out-of-memory (OOM) conditions. The standard
+library calls the `abort` intrinsic, which just calls an illegal instruction to
+crash the whole program. The reason we abort and don't panic is because
+unwinding can cause allocations to happen, and that seems like a bad thing to do
+when your allocator just came back with "hey I don't have any more memory".
+
+Of course, this is a bit silly since most platforms don't actually run out of
+memory in a conventional way. Your operating system will probably kill the
+application by another means if you legitimately start using up all the memory.
+The most likely way we'll trigger OOM is by just asking for ludicrous quantities
+of memory at once (e.g. half the theoretical address space). As such it's
+*probably* fine to panic and nothing bad will happen. Still, we're trying to be
+like the standard library as much as possible, so we'll just kill the whole
+program.
+
+We said we don't want to use intrinsics, so doing exactly what `std` does is
+out. Instead, we'll call `std::process::exit` with some random number.
+
+```rust
+fn oom() {
+    ::std::process::exit(-9999);
+}
+```
+
+Okay, now we can write growing. Roughly, we want to have this logic:
+
+```text
+if cap == 0:
+    allocate()
+    cap = 1
+else:
+    reallocate()
+    cap *= 2
+```
+
+But Rust's only supported allocator API is so low level that we'll need to do a
+fair bit of extra work. We also need to guard against some special
+conditions that can occur with really large allocations or empty allocations.
+
+In particular, `ptr::offset` will cause us a lot of trouble, because it has
+the semantics of LLVM's GEP inbounds instruction. If you're fortunate enough to
+not have dealt with this instruction, here's the basic story with GEP: alias
+analysis, alias analysis, alias analysis. It's super important to an optimizing
+compiler to be able to reason about data dependencies and aliasing.
+
+As a simple example, consider the following fragment of code:
+
+```rust
+# let x = &mut 0;
+# let y = &mut 0;
+*x *= 7;
+*y *= 3;
+```
+
+If the compiler can prove that `x` and `y` point to different locations in
+memory, the two operations can in theory be executed in parallel (by e.g.
+loading them into different registers and working on them independently).
+However the compiler can't do this in general because if x and y point to
+the same location in memory, the operations need to be done to the same value,
+and they can't just be merged afterwards.
+
+When you use GEP inbounds, you are specifically telling LLVM that the offsets
+you're about to do are within the bounds of a single "allocated" entity. The
+ultimate payoff being that LLVM can assume that if two pointers are known to
+point to two disjoint objects, all the offsets of those pointers are *also*
+known to not alias (because you won't just end up in some random place in
+memory). LLVM is heavily optimized to work with GEP offsets, and inbounds
+offsets are the best of all, so it's important that we use them as much as
+possible.
+
+So that's what GEP's about, how can it cause us trouble?
+
+The first problem is that we index into arrays with unsigned integers, but
+GEP (and as a consequence `ptr::offset`) takes a signed integer. This means
+that half of the seemingly valid indices into an array will overflow GEP and
+actually go in the wrong direction! As such we must limit all allocations to
+`isize::MAX` elements. This actually means we only need to worry about
+byte-sized objects, because e.g. `> isize::MAX` `u16`s will truly exhaust all of
+the system's memory. However in order to avoid subtle corner cases where someone
+reinterprets some array of `< isize::MAX` objects as bytes, std limits all
+allocations to `isize::MAX` bytes.
+
+On all 64-bit targets that Rust currently supports we're artificially limited
+to significantly less than all 64 bits of the address space (modern x64
+platforms only expose 48-bit addressing), so we can rely on just running out of
+memory first. However on 32-bit targets, particularly those with extensions to
+use more of the address space (PAE x86 or x32), it's theoretically possible to
+successfully allocate more than `isize::MAX` bytes of memory.
+
+However since this is a tutorial, we're not going to be particularly optimal
+here, and just unconditionally check, rather than use clever platform-specific
+`cfg`s.
+
+The other corner-case we need to worry about is empty allocations. There will
+be two kinds of empty allocations we need to worry about: `cap = 0` for all T,
+and `cap > 0` for zero-sized types.
+
+These cases are tricky because they come
+down to what LLVM means by "allocated". LLVM's notion of an
+allocation is significantly more abstract than how we usually use it. Because
+LLVM needs to work with different languages' semantics and custom allocators,
+it can't really intimately understand allocation. Instead, the main idea behind
+allocation is "doesn't overlap with other stuff". That is, heap allocations,
+stack allocations, and globals don't randomly overlap. Yep, it's about alias
+analysis. As such, Rust can technically play a bit fast an loose with the notion of
+an allocation as long as it's *consistent*.
+
+Getting back to the empty allocation case, there are a couple of places where
+we want to offset by 0 as a consequence of generic code. The question is then:
+is it consistent to do so? For zero-sized types, we have concluded that it is
+indeed consistent to do a GEP inbounds offset by an arbitrary number of
+elements. This is a runtime no-op because every element takes up no space,
+and it's fine to pretend that there's infinite zero-sized types allocated
+at `0x01`. No allocator will ever allocate that address, because they won't
+allocate `0x00` and they generally allocate to some minimal alignment higher
+than a byte. Also generally the whole first page of memory is
+protected from being allocated anyway (a whole 4k, on many platforms).
+
+However what about for positive-sized types? That one's a bit trickier. In
+principle, you can argue that offsetting by 0 gives LLVM no information: either
+there's an element before the address or after it, but it can't know which.
+However we've chosen to conservatively assume that it may do bad things. As
+such we will guard against this case explicitly.
+
+*Phew*
+
+Ok with all the nonsense out of the way, let's actually allocate some memory:
+
+```rust,ignore
+fn grow(&mut self) {
+    // this is all pretty delicate, so let's say it's all unsafe
+    unsafe {
+        // current API requires us to specify size and alignment manually.
+        let align = mem::align_of::<T>();
+        let elem_size = mem::size_of::<T>();
+
+        let (new_cap, ptr) = if self.cap == 0 {
+            let ptr = heap::allocate(elem_size, align);
+            (1, ptr)
+        } else {
+            // as an invariant, we can assume that `self.cap < isize::MAX`,
+            // so this doesn't need to be checked.
+            let new_cap = self.cap * 2;
+            // Similarly this can't overflow due to previously allocating this
+            let old_num_bytes = self.cap * elem_size;
+
+            // check that the new allocation doesn't exceed `isize::MAX` at all
+            // regardless of the actual size of the capacity. This combines the
+            // `new_cap <= isize::MAX` and `new_num_bytes <= usize::MAX` checks
+            // we need to make. We lose the ability to allocate e.g. 2/3rds of
+            // the address space with a single Vec of i16's on 32-bit though.
+            // Alas, poor Yorick -- I knew him, Horatio.
+            assert!(old_num_bytes <= (::std::isize::MAX as usize) / 2,
+                    "capacity overflow");
+
+            let new_num_bytes = old_num_bytes * 2;
+            let ptr = heap::reallocate(*self.ptr as *mut _,
+                                        old_num_bytes,
+                                        new_num_bytes,
+                                        align);
+            (new_cap, ptr)
+        };
+
+        // If allocate or reallocate fail, we'll get `null` back
+        if ptr.is_null() { oom(); }
+
+        self.ptr = Unique::new(ptr as *mut _);
+        self.cap = new_cap;
+    }
+}
+```
+
+Nothing particularly tricky here. Just computing sizes and alignments and doing
+some careful multiplication checks.
+
diff --git a/src/doc/nomicon/vec-dealloc.md b/src/doc/nomicon/vec-dealloc.md
new file mode 100644
index 00000000000..b767caa4912
--- /dev/null
+++ b/src/doc/nomicon/vec-dealloc.md
@@ -0,0 +1,29 @@
+% Deallocating
+
+Next we should implement Drop so that we don't massively leak tons of resources.
+The easiest way is to just call `pop` until it yields None, and then deallocate
+our buffer. Note that calling `pop` is unneeded if `T: !Drop`. In theory we can
+ask Rust if `T` `needs_drop` and omit the calls to `pop`. However in practice
+LLVM is *really* good at removing simple side-effect free code like this, so I
+wouldn't bother unless you notice it's not being stripped (in this case it is).
+
+We must not call `heap::deallocate` when `self.cap == 0`, as in this case we
+haven't actually allocated any memory.
+
+
+```rust,ignore
+impl<T> Drop for Vec<T> {
+    fn drop(&mut self) {
+        if self.cap != 0 {
+            while let Some(_) = self.pop() { }
+
+            let align = mem::align_of::<T>();
+            let elem_size = mem::size_of::<T>();
+            let num_bytes = elem_size * self.cap;
+            unsafe {
+                heap::deallocate(*self.ptr, num_bytes, align);
+            }
+        }
+    }
+}
+```
diff --git a/src/doc/nomicon/vec-deref.md b/src/doc/nomicon/vec-deref.md
new file mode 100644
index 00000000000..6460eab479b
--- /dev/null
+++ b/src/doc/nomicon/vec-deref.md
@@ -0,0 +1,42 @@
+% Deref
+
+Alright! We've got a decent minimal stack implemented. We can push, we can
+pop, and we can clean up after ourselves. However there's a whole mess of
+functionality we'd reasonably want. In particular, we have a proper array, but
+none of the slice functionality. That's actually pretty easy to solve: we can
+implement `Deref<Target=[T]>`. This will magically make our Vec coerce to, and
+behave like, a slice in all sorts of conditions.
+
+All we need is `slice::from_raw_parts`. It will correctly handle empty slices
+for us. Later once we set up zero-sized type support it will also Just Work
+for those too.
+
+```rust,ignore
+use std::ops::Deref;
+
+impl<T> Deref for Vec<T> {
+    type Target = [T];
+    fn deref(&self) -> &[T] {
+        unsafe {
+            ::std::slice::from_raw_parts(*self.ptr, self.len)
+        }
+    }
+}
+```
+
+And let's do DerefMut too:
+
+```rust,ignore
+use std::ops::DerefMut;
+
+impl<T> DerefMut for Vec<T> {
+    fn deref_mut(&mut self) -> &mut [T] {
+        unsafe {
+            ::std::slice::from_raw_parts_mut(*self.ptr, self.len)
+        }
+    }
+}
+```
+
+Now we have `len`, `first`, `last`, indexing, slicing, sorting, `iter`,
+`iter_mut`, and all other sorts of bells and whistles provided by slice. Sweet!
diff --git a/src/doc/nomicon/vec-drain.md b/src/doc/nomicon/vec-drain.md
new file mode 100644
index 00000000000..4521bbdd05e
--- /dev/null
+++ b/src/doc/nomicon/vec-drain.md
@@ -0,0 +1,150 @@
+% Drain
+
+Let's move on to Drain. Drain is largely the same as IntoIter, except that
+instead of consuming the Vec, it borrows the Vec and leaves its allocation
+untouched. For now we'll only implement the "basic" full-range version.
+
+```rust,ignore
+use std::marker::PhantomData;
+
+struct Drain<'a, T: 'a> {
+    // Need to bound the lifetime here, so we do it with `&'a mut Vec<T>`
+    // because that's semantically what we contain. We're "just" calling
+    // `pop()` and `remove(0)`.
+    vec: PhantomData<&'a mut Vec<T>>
+    start: *const T,
+    end: *const T,
+}
+
+impl<'a, T> Iterator for Drain<'a, T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> {
+        if self.start == self.end {
+            None
+```
+
+-- wait, this is seeming familiar. Let's do some more compression. Both
+IntoIter and Drain have the exact same structure, let's just factor it out.
+
+```rust
+struct RawValIter<T> {
+    start: *const T,
+    end: *const T,
+}
+
+impl<T> RawValIter<T> {
+    // unsafe to construct because it has no associated lifetimes.
+    // This is necessary to store a RawValIter in the same struct as
+    // its actual allocation. OK since it's a private implementation
+    // detail.
+    unsafe fn new(slice: &[T]) -> Self {
+        RawValIter {
+            start: slice.as_ptr(),
+            end: if slice.len() == 0 {
+                // if `len = 0`, then this is not actually allocated memory.
+                // Need to avoid offsetting because that will give wrong
+                // information to LLVM via GEP.
+                slice.as_ptr()
+            } else {
+                slice.as_ptr().offset(slice.len() as isize)
+            }
+        }
+    }
+}
+
+// Iterator and DoubleEndedIterator impls identical to IntoIter.
+```
+
+And IntoIter becomes the following:
+
+```rust,ignore
+pub struct IntoIter<T> {
+    _buf: RawVec<T>, // we don't actually care about this. Just need it to live.
+    iter: RawValIter<T>,
+}
+
+impl<T> Iterator for IntoIter<T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+
+impl<T> DoubleEndedIterator for IntoIter<T> {
+    fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
+}
+
+impl<T> Drop for IntoIter<T> {
+    fn drop(&mut self) {
+        for _ in &mut self.iter {}
+    }
+}
+
+impl<T> Vec<T> {
+    pub fn into_iter(self) -> IntoIter<T> {
+        unsafe {
+            let iter = RawValIter::new(&self);
+
+            let buf = ptr::read(&self.buf);
+            mem::forget(self);
+
+            IntoIter {
+                iter: iter,
+                _buf: buf,
+            }
+        }
+    }
+}
+```
+
+Note that I've left a few quirks in this design to make upgrading Drain to work
+with arbitrary subranges a bit easier. In particular we *could* have RawValIter
+drain itself on drop, but that won't work right for a more complex Drain.
+We also take a slice to simplify Drain initialization.
+
+Alright, now Drain is really easy:
+
+```rust,ignore
+use std::marker::PhantomData;
+
+pub struct Drain<'a, T: 'a> {
+    vec: PhantomData<&'a mut Vec<T>>,
+    iter: RawValIter<T>,
+}
+
+impl<'a, T> Iterator for Drain<'a, T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+
+impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
+    fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
+}
+
+impl<'a, T> Drop for Drain<'a, T> {
+    fn drop(&mut self) {
+        for _ in &mut self.iter {}
+    }
+}
+
+impl<T> Vec<T> {
+    pub fn drain(&mut self) -> Drain<T> {
+        // this is a mem::forget safety thing. If Drain is forgotten, we just
+        // leak the whole Vec's contents. Also we need to do this eventually
+        // anyway, so why not do it now?
+        self.len = 0;
+
+        unsafe {
+            Drain {
+                iter: RawValIter::new(&self),
+                vec: PhantomData,
+            }
+        }
+    }
+}
+```
+
+For more details on the `mem::forget` problem, see the
+[section on leaks][leaks].
+
+[leaks]: leaking.html
diff --git a/src/doc/nomicon/vec-final.md b/src/doc/nomicon/vec-final.md
new file mode 100644
index 00000000000..847957e2ea9
--- /dev/null
+++ b/src/doc/nomicon/vec-final.md
@@ -0,0 +1,311 @@
+% The Final Code
+
+```rust
+#![feature(unique)]
+#![feature(heap_api)]
+
+use std::ptr::{Unique, self};
+use std::rt::heap;
+use std::mem;
+use std::ops::{Deref, DerefMut};
+use std::marker::PhantomData;
+
+
+
+
+
+struct RawVec<T> {
+    ptr: Unique<T>,
+    cap: usize,
+}
+
+impl<T> RawVec<T> {
+    fn new() -> Self {
+        unsafe {
+            // !0 is usize::MAX. This branch should be stripped at compile time.
+            let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
+
+            // heap::EMPTY doubles as "unallocated" and "zero-sized allocation"
+            RawVec { ptr: Unique::new(heap::EMPTY as *mut T), cap: cap }
+        }
+    }
+
+    fn grow(&mut self) {
+        unsafe {
+            let elem_size = mem::size_of::<T>();
+
+            // since we set the capacity to usize::MAX when elem_size is
+            // 0, getting to here necessarily means the Vec is overfull.
+            assert!(elem_size != 0, "capacity overflow");
+
+            let align = mem::align_of::<T>();
+
+            let (new_cap, ptr) = if self.cap == 0 {
+                let ptr = heap::allocate(elem_size, align);
+                (1, ptr)
+            } else {
+                let new_cap = 2 * self.cap;
+                let ptr = heap::reallocate(*self.ptr as *mut _,
+                                            self.cap * elem_size,
+                                            new_cap * elem_size,
+                                            align);
+                (new_cap, ptr)
+            };
+
+            // If allocate or reallocate fail, we'll get `null` back
+            if ptr.is_null() { oom() }
+
+            self.ptr = Unique::new(ptr as *mut _);
+            self.cap = new_cap;
+        }
+    }
+}
+
+impl<T> Drop for RawVec<T> {
+    fn drop(&mut self) {
+        let elem_size = mem::size_of::<T>();
+        if self.cap != 0 && elem_size != 0 {
+            let align = mem::align_of::<T>();
+
+            let num_bytes = elem_size * self.cap;
+            unsafe {
+                heap::deallocate(*self.ptr as *mut _, num_bytes, align);
+            }
+        }
+    }
+}
+
+
+
+
+
+pub struct Vec<T> {
+    buf: RawVec<T>,
+    len: usize,
+}
+
+impl<T> Vec<T> {
+    fn ptr(&self) -> *mut T { *self.buf.ptr }
+
+    fn cap(&self) -> usize { self.buf.cap }
+
+    pub fn new() -> Self {
+        Vec { buf: RawVec::new(), len: 0 }
+    }
+    pub fn push(&mut self, elem: T) {
+        if self.len == self.cap() { self.buf.grow(); }
+
+        unsafe {
+            ptr::write(self.ptr().offset(self.len as isize), elem);
+        }
+
+        // Can't fail, we'll OOM first.
+        self.len += 1;
+    }
+
+    pub fn pop(&mut self) -> Option<T> {
+        if self.len == 0 {
+            None
+        } else {
+            self.len -= 1;
+            unsafe {
+                Some(ptr::read(self.ptr().offset(self.len as isize)))
+            }
+        }
+    }
+
+    pub fn insert(&mut self, index: usize, elem: T) {
+        assert!(index <= self.len, "index out of bounds");
+        if self.cap() == self.len { self.buf.grow(); }
+
+        unsafe {
+            if index < self.len {
+                ptr::copy(self.ptr().offset(index as isize),
+                          self.ptr().offset(index as isize + 1),
+                          self.len - index);
+            }
+            ptr::write(self.ptr().offset(index as isize), elem);
+            self.len += 1;
+        }
+    }
+
+    pub fn remove(&mut self, index: usize) -> T {
+        assert!(index < self.len, "index out of bounds");
+        unsafe {
+            self.len -= 1;
+            let result = ptr::read(self.ptr().offset(index as isize));
+            ptr::copy(self.ptr().offset(index as isize + 1),
+                      self.ptr().offset(index as isize),
+                      self.len - index);
+            result
+        }
+    }
+
+    pub fn into_iter(self) -> IntoIter<T> {
+        unsafe {
+            let iter = RawValIter::new(&self);
+            let buf = ptr::read(&self.buf);
+            mem::forget(self);
+
+            IntoIter {
+                iter: iter,
+                _buf: buf,
+            }
+        }
+    }
+
+    pub fn drain(&mut self) -> Drain<T> {
+        // this is a mem::forget safety thing. If this is forgotten, we just
+        // leak the whole Vec's contents. Also we need to do this *eventually*
+        // anyway, so why not do it now?
+        self.len = 0;
+        unsafe {
+            Drain {
+                iter: RawValIter::new(&self),
+                vec: PhantomData,
+            }
+        }
+    }
+}
+
+impl<T> Drop for Vec<T> {
+    fn drop(&mut self) {
+        while let Some(_) = self.pop() {}
+        // allocation is handled by RawVec
+    }
+}
+
+impl<T> Deref for Vec<T> {
+    type Target = [T];
+    fn deref(&self) -> &[T] {
+        unsafe {
+            ::std::slice::from_raw_parts(self.ptr(), self.len)
+        }
+    }
+}
+
+impl<T> DerefMut for Vec<T> {
+    fn deref_mut(&mut self) -> &mut [T] {
+        unsafe {
+            ::std::slice::from_raw_parts_mut(self.ptr(), self.len)
+        }
+    }
+}
+
+
+
+
+
+struct RawValIter<T> {
+    start: *const T,
+    end: *const T,
+}
+
+impl<T> RawValIter<T> {
+    unsafe fn new(slice: &[T]) -> Self {
+        RawValIter {
+            start: slice.as_ptr(),
+            end: if mem::size_of::<T>() == 0 {
+                ((slice.as_ptr() as usize) + slice.len()) as *const _
+            } else if slice.len() == 0 {
+                slice.as_ptr()
+            } else {
+                slice.as_ptr().offset(slice.len() as isize)
+            }
+        }
+    }
+}
+
+impl<T> Iterator for RawValIter<T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> {
+        if self.start == self.end {
+            None
+        } else {
+            unsafe {
+                let result = ptr::read(self.start);
+                self.start = self.start.offset(1);
+                Some(result)
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let elem_size = mem::size_of::<T>();
+        let len = (self.end as usize - self.start as usize)
+                  / if elem_size == 0 { 1 } else { elem_size };
+        (len, Some(len))
+    }
+}
+
+impl<T> DoubleEndedIterator for RawValIter<T> {
+    fn next_back(&mut self) -> Option<T> {
+        if self.start == self.end {
+            None
+        } else {
+            unsafe {
+                self.end = self.end.offset(-1);
+                Some(ptr::read(self.end))
+            }
+        }
+    }
+}
+
+
+
+
+pub struct IntoIter<T> {
+    _buf: RawVec<T>, // we don't actually care about this. Just need it to live.
+    iter: RawValIter<T>,
+}
+
+impl<T> Iterator for IntoIter<T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> { self.iter.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+
+impl<T> DoubleEndedIterator for IntoIter<T> {
+    fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
+}
+
+impl<T> Drop for IntoIter<T> {
+    fn drop(&mut self) {
+        for _ in &mut *self {}
+    }
+}
+
+
+
+
+pub struct Drain<'a, T: 'a> {
+    vec: PhantomData<&'a mut Vec<T>>,
+    iter: RawValIter<T>,
+}
+
+impl<'a, T> Iterator for Drain<'a, T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> { self.iter.next_back() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+}
+
+impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
+    fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
+}
+
+impl<'a, T> Drop for Drain<'a, T> {
+    fn drop(&mut self) {
+        // pre-drain the iter
+        for _ in &mut self.iter {}
+    }
+}
+
+/// Abort the process, we're out of memory!
+///
+/// In practice this is probably dead code on most OSes
+fn oom() {
+    ::std::process::exit(-9999);
+}
+
+# fn main() {}
+```
diff --git a/src/doc/nomicon/vec-insert-remove.md b/src/doc/nomicon/vec-insert-remove.md
new file mode 100644
index 00000000000..0a37170c52c
--- /dev/null
+++ b/src/doc/nomicon/vec-insert-remove.md
@@ -0,0 +1,51 @@
+% Insert and Remove
+
+Something *not* provided by slice is `insert` and `remove`, so let's do those
+next.
+
+Insert needs to shift all the elements at the target index to the right by one.
+To do this we need to use `ptr::copy`, which is our version of C's `memmove`.
+This copies some chunk of memory from one location to another, correctly
+handling the case where the source and destination overlap (which will
+definitely happen here).
+
+If we insert at index `i`, we want to shift the `[i .. len]` to `[i+1 .. len+1]`
+using the old len.
+
+```rust,ignore
+pub fn insert(&mut self, index: usize, elem: T) {
+    // Note: `<=` because it's valid to insert after everything
+    // which would be equivalent to push.
+    assert!(index <= self.len, "index out of bounds");
+    if self.cap == self.len { self.grow(); }
+
+    unsafe {
+        if index < self.len {
+            // ptr::copy(src, dest, len): "copy from source to dest len elems"
+            ptr::copy(self.ptr.offset(index as isize),
+                      self.ptr.offset(index as isize + 1),
+                      len - index);
+        }
+        ptr::write(self.ptr.offset(index as isize), elem);
+        self.len += 1;
+    }
+}
+```
+
+Remove behaves in the opposite manner. We need to shift all the elements from
+`[i+1 .. len + 1]` to `[i .. len]` using the *new* len.
+
+```rust,ignore
+pub fn remove(&mut self, index: usize) -> T {
+    // Note: `<` because it's *not* valid to remove after everything
+    assert!(index < self.len, "index out of bounds");
+    unsafe {
+        self.len -= 1;
+        let result = ptr::read(self.ptr.offset(index as isize));
+        ptr::copy(self.ptr.offset(index as isize + 1),
+                  self.ptr.offset(index as isize),
+                  len - index);
+        result
+    }
+}
+```
diff --git a/src/doc/nomicon/vec-into-iter.md b/src/doc/nomicon/vec-into-iter.md
new file mode 100644
index 00000000000..ebb0a79bb65
--- /dev/null
+++ b/src/doc/nomicon/vec-into-iter.md
@@ -0,0 +1,147 @@
+% IntoIter
+
+Let's move on to writing iterators. `iter` and `iter_mut` have already been
+written for us thanks to The Magic of Deref. However there's two interesting
+iterators that Vec provides that slices can't: `into_iter` and `drain`.
+
+IntoIter consumes the Vec by-value, and can consequently yield its elements
+by-value. In order to enable this, IntoIter needs to take control of Vec's
+allocation.
+
+IntoIter needs to be DoubleEnded as well, to enable reading from both ends.
+Reading from the back could just be implemented as calling `pop`, but reading
+from the front is harder. We could call `remove(0)` but that would be insanely
+expensive. Instead we're going to just use ptr::read to copy values out of
+either end of the Vec without mutating the buffer at all.
+
+To do this we're going to use a very common C idiom for array iteration. We'll
+make two pointers; one that points to the start of the array, and one that
+points to one-element past the end. When we want an element from one end, we'll
+read out the value pointed to at that end and move the pointer over by one. When
+the two pointers are equal, we know we're done.
+
+Note that the order of read and offset are reversed for `next` and `next_back`
+For `next_back` the pointer is always after the element it wants to read next,
+while for `next` the pointer is always at the element it wants to read next.
+To see why this is, consider the case where every element but one has been
+yielded.
+
+The array looks like this:
+
+```text
+          S  E
+[X, X, X, O, X, X, X]
+```
+
+If E pointed directly at the element it wanted to yield next, it would be
+indistinguishable from the case where there are no more elements to yield.
+
+Although we don't actually care about it during iteration, we also need to hold
+onto the Vec's allocation information in order to free it once IntoIter is
+dropped.
+
+So we're going to use the following struct:
+
+```rust,ignore
+struct IntoIter<T> {
+    buf: Unique<T>,
+    cap: usize,
+    start: *const T,
+    end: *const T,
+}
+```
+
+And this is what we end up with for initialization:
+
+```rust,ignore
+impl<T> Vec<T> {
+    fn into_iter(self) -> IntoIter<T> {
+        // Can't destructure Vec since it's Drop
+        let ptr = self.ptr;
+        let cap = self.cap;
+        let len = self.len;
+
+        // Make sure not to drop Vec since that will free the buffer
+        mem::forget(self);
+
+        unsafe {
+            IntoIter {
+                buf: ptr,
+                cap: cap,
+                start: *ptr,
+                end: if cap == 0 {
+                    // can't offset off this pointer, it's not allocated!
+                    *ptr
+                } else {
+                    ptr.offset(len as isize)
+                }
+            }
+        }
+    }
+}
+```
+
+Here's iterating forward:
+
+```rust,ignore
+impl<T> Iterator for IntoIter<T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> {
+        if self.start == self.end {
+            None
+        } else {
+            unsafe {
+                let result = ptr::read(self.start);
+                self.start = self.start.offset(1);
+                Some(result)
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = (self.end as usize - self.start as usize)
+                  / mem::size_of::<T>();
+        (len, Some(len))
+    }
+}
+```
+
+And here's iterating backwards.
+
+```rust,ignore
+impl<T> DoubleEndedIterator for IntoIter<T> {
+    fn next_back(&mut self) -> Option<T> {
+        if self.start == self.end {
+            None
+        } else {
+            unsafe {
+                self.end = self.end.offset(-1);
+                Some(ptr::read(self.end))
+            }
+        }
+    }
+}
+```
+
+Because IntoIter takes ownership of its allocation, it needs to implement Drop
+to free it. However it also wants to implement Drop to drop any elements it
+contains that weren't yielded.
+
+
+```rust,ignore
+impl<T> Drop for IntoIter<T> {
+    fn drop(&mut self) {
+        if self.cap != 0 {
+            // drop any remaining elements
+            for _ in &mut *self {}
+
+            let align = mem::align_of::<T>();
+            let elem_size = mem::size_of::<T>();
+            let num_bytes = elem_size * self.cap;
+            unsafe {
+                heap::deallocate(*self.buf as *mut _, num_bytes, align);
+            }
+        }
+    }
+}
+```
diff --git a/src/doc/nomicon/vec-layout.md b/src/doc/nomicon/vec-layout.md
new file mode 100644
index 00000000000..3df63d5249c
--- /dev/null
+++ b/src/doc/nomicon/vec-layout.md
@@ -0,0 +1,100 @@
+% Layout
+
+First off, we need to come up with the struct layout. A Vec has three parts:
+a pointer to the allocation, the size of the allocation, and the number of
+elements that have been initialized.
+
+Naively, this means we just want this design:
+
+```rust
+pub struct Vec<T> {
+    ptr: *mut T,
+    cap: usize,
+    len: usize,
+}
+# fn main() {}
+```
+
+And indeed this would compile. Unfortunately, it would be incorrect. First, the
+compiler will give us too strict variance. So a `&Vec<&'static str>`
+couldn't be used where an `&Vec<&'a str>` was expected. More importantly, it
+will give incorrect ownership information to the drop checker, as it will
+conservatively assume we don't own any values of type `T`. See [the chapter
+on ownership and lifetimes][ownership] for all the details on variance and
+drop check.
+
+As we saw in the ownership chapter, we should use `Unique<T>` in place of
+`*mut T` when we have a raw pointer to an allocation we own. Unique is unstable,
+so we'd like to not use it if possible, though.
+
+As a recap, Unique is a wrapper around a raw pointer that declares that:
+
+* We are variant over `T`
+* We may own a value of type `T` (for drop check)
+* We are Send/Sync if `T` is Send/Sync
+* We deref to `*mut T` (so it largely acts like a `*mut` in our code)
+* Our pointer is never null (so `Option<Vec<T>>` is null-pointer-optimized)
+
+We can implement all of the above requirements except for the last
+one in stable Rust:
+
+```rust
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::mem;
+
+struct Unique<T> {
+    ptr: *const T,              // *const for variance
+    _marker: PhantomData<T>,    // For the drop checker
+}
+
+// Deriving Send and Sync is safe because we are the Unique owners
+// of this data. It's like Unique<T> is "just" T.
+unsafe impl<T: Send> Send for Unique<T> {}
+unsafe impl<T: Sync> Sync for Unique<T> {}
+
+impl<T> Unique<T> {
+    pub fn new(ptr: *mut T) -> Self {
+        Unique { ptr: ptr, _marker: PhantomData }
+    }
+}
+
+impl<T> Deref for Unique<T> {
+    type Target = *mut T;
+    fn deref(&self) -> &*mut T {
+        // There's no way to cast the *const to a *mut
+        // while also taking a reference. So we just
+        // transmute it since it's all "just pointers".
+        unsafe { mem::transmute(&self.ptr) }
+    }
+}
+# fn main() {}
+```
+
+Unfortunately the mechanism for stating that your value is non-zero is
+unstable and unlikely to be stabilized soon. As such we're just going to
+take the hit and use std's Unique:
+
+
+```rust
+#![feature(unique)]
+
+use std::ptr::{Unique, self};
+
+pub struct Vec<T> {
+    ptr: Unique<T>,
+    cap: usize,
+    len: usize,
+}
+
+# fn main() {}
+```
+
+If you don't care about the null-pointer optimization, then you can use the
+stable code. However we will be designing the rest of the code around enabling
+the optimization. In particular, `Unique::new` is unsafe to call, because
+putting `null` inside of it is Undefined Behaviour. Our stable Unique doesn't
+need `new` to be unsafe because it doesn't make any interesting guarantees about
+its contents.
+
+[ownership]: ownership.html
diff --git a/src/doc/nomicon/vec-push-pop.md b/src/doc/nomicon/vec-push-pop.md
new file mode 100644
index 00000000000..b518e8aa48f
--- /dev/null
+++ b/src/doc/nomicon/vec-push-pop.md
@@ -0,0 +1,55 @@
+% Push and Pop
+
+Alright. We can initialize. We can allocate. Let's actually implement some
+functionality! Let's start with `push`. All it needs to do is check if we're
+full to grow, unconditionally write to the next index, and then increment our
+length.
+
+To do the write we have to be careful not to evaluate the memory we want to write
+to. At worst, it's truly uninitialized memory from the allocator. At best it's the
+bits of some old value we popped off. Either way, we can't just index to the memory
+and dereference it, because that will evaluate the memory as a valid instance of
+T. Worse, `foo[idx] = x` will try to call `drop` on the old value of `foo[idx]`!
+
+The correct way to do this is with `ptr::write`, which just blindly overwrites the
+target address with the bits of the value we provide. No evaluation involved.
+
+For `push`, if the old len (before push was called) is 0, then we want to write
+to the 0th index. So we should offset by the old len.
+
+```rust,ignore
+pub fn push(&mut self, elem: T) {
+    if self.len == self.cap { self.grow(); }
+
+    unsafe {
+        ptr::write(self.ptr.offset(self.len as isize), elem);
+    }
+
+    // Can't fail, we'll OOM first.
+    self.len += 1;
+}
+```
+
+Easy! How about `pop`? Although this time the index we want to access is
+initialized, Rust won't just let us dereference the location of memory to move
+the value out, because that would leave the memory uninitialized! For this we
+need `ptr::read`, which just copies out the bits from the target address and
+intrprets it as a value of type T. This will leave the memory at this address
+logically uninitialized, even though there is in fact a perfectly good instance
+of T there.
+
+For `pop`, if the old len is 1, we want to read out of the 0th index. So we
+should offset by the new len.
+
+```rust,ignore
+pub fn pop(&mut self) -> Option<T> {
+    if self.len == 0 {
+        None
+    } else {
+        self.len -= 1;
+        unsafe {
+            Some(ptr::read(self.ptr.offset(self.len as isize)))
+        }
+    }
+}
+```
diff --git a/src/doc/nomicon/vec-raw.md b/src/doc/nomicon/vec-raw.md
new file mode 100644
index 00000000000..8f78462cf40
--- /dev/null
+++ b/src/doc/nomicon/vec-raw.md
@@ -0,0 +1,136 @@
+% RawVec
+
+We've actually reached an interesting situation here: we've duplicated the logic
+for specifying a buffer and freeing its memory in Vec and IntoIter. Now that
+we've implemented it and identified *actual* logic duplication, this is a good
+time to perform some logic compression.
+
+We're going to abstract out the `(ptr, cap)` pair and give them the logic for
+allocating, growing, and freeing:
+
+```rust,ignore
+struct RawVec<T> {
+    ptr: Unique<T>,
+    cap: usize,
+}
+
+impl<T> RawVec<T> {
+    fn new() -> Self {
+        assert!(mem::size_of::<T>() != 0, "TODO: implement ZST support");
+        unsafe {
+            RawVec { ptr: Unique::new(heap::EMPTY as *mut T), cap: 0 }
+        }
+    }
+
+    // unchanged from Vec
+    fn grow(&mut self) {
+        unsafe {
+            let align = mem::align_of::<T>();
+            let elem_size = mem::size_of::<T>();
+
+            let (new_cap, ptr) = if self.cap == 0 {
+                let ptr = heap::allocate(elem_size, align);
+                (1, ptr)
+            } else {
+                let new_cap = 2 * self.cap;
+                let ptr = heap::reallocate(*self.ptr as *mut _,
+                                            self.cap * elem_size,
+                                            new_cap * elem_size,
+                                            align);
+                (new_cap, ptr)
+            };
+
+            // If allocate or reallocate fail, we'll get `null` back
+            if ptr.is_null() { oom() }
+
+            self.ptr = Unique::new(ptr as *mut _);
+            self.cap = new_cap;
+        }
+    }
+}
+
+
+impl<T> Drop for RawVec<T> {
+    fn drop(&mut self) {
+        if self.cap != 0 {
+            let align = mem::align_of::<T>();
+            let elem_size = mem::size_of::<T>();
+            let num_bytes = elem_size * self.cap;
+            unsafe {
+                heap::deallocate(*self.ptr as *mut _, num_bytes, align);
+            }
+        }
+    }
+}
+```
+
+And change Vec as follows:
+
+```rust,ignore
+pub struct Vec<T> {
+    buf: RawVec<T>,
+    len: usize,
+}
+
+impl<T> Vec<T> {
+    fn ptr(&self) -> *mut T { *self.buf.ptr }
+
+    fn cap(&self) -> usize { self.buf.cap }
+
+    pub fn new() -> Self {
+        Vec { buf: RawVec::new(), len: 0 }
+    }
+
+    // push/pop/insert/remove largely unchanged:
+    // * `self.ptr -> self.ptr()`
+    // * `self.cap -> self.cap()`
+    // * `self.grow -> self.buf.grow()`
+}
+
+impl<T> Drop for Vec<T> {
+    fn drop(&mut self) {
+        while let Some(_) = self.pop() {}
+        // deallocation is handled by RawVec
+    }
+}
+```
+
+And finally we can really simplify IntoIter:
+
+```rust,ignore
+struct IntoIter<T> {
+    _buf: RawVec<T>, // we don't actually care about this. Just need it to live.
+    start: *const T,
+    end: *const T,
+}
+
+// next and next_back literally unchanged since they never referred to the buf
+
+impl<T> Drop for IntoIter<T> {
+    fn drop(&mut self) {
+        // only need to ensure all our elements are read;
+        // buffer will clean itself up afterwards.
+        for _ in &mut *self {}
+    }
+}
+
+impl<T> Vec<T> {
+    pub fn into_iter(self) -> IntoIter<T> {
+        unsafe {
+            // need to use ptr::read to unsafely move the buf out since it's
+            // not Copy, and Vec implements Drop (so we can't destructure it).
+            let buf = ptr::read(&self.buf);
+            let len = self.len;
+            mem::forget(self);
+
+            IntoIter {
+                start: *buf.ptr,
+                end: buf.ptr.offset(len as isize),
+                _buf: buf,
+            }
+        }
+    }
+}
+```
+
+Much better.
diff --git a/src/doc/nomicon/vec-zsts.md b/src/doc/nomicon/vec-zsts.md
new file mode 100644
index 00000000000..72e8a34488b
--- /dev/null
+++ b/src/doc/nomicon/vec-zsts.md
@@ -0,0 +1,176 @@
+% Handling Zero-Sized Types
+
+It's time. We're going to fight the spectre that is zero-sized types. Safe Rust
+*never* needs to care about this, but Vec is very intensive on raw pointers and
+raw allocations, which are exactly the two things that care about
+zero-sized types. We need to be careful of two things:
+
+* The raw allocator API has undefined behaviour if you pass in 0 for an
+  allocation size.
+* raw pointer offsets are no-ops for zero-sized types, which will break our
+  C-style pointer iterator.
+
+Thankfully we abstracted out pointer-iterators and allocating handling into
+RawValIter and RawVec respectively. How mysteriously convenient.
+
+
+
+
+## Allocating Zero-Sized Types
+
+So if the allocator API doesn't support zero-sized allocations, what on earth
+do we store as our allocation? Why, `heap::EMPTY` of course! Almost every operation
+with a ZST is a no-op since ZSTs have exactly one value, and therefore no state needs
+to be considered to store or load them. This actually extends to `ptr::read` and
+`ptr::write`: they won't actually look at the pointer at all. As such we never need
+to change the pointer.
+
+Note however that our previous reliance on running out of memory before overflow is
+no longer valid with zero-sized types. We must explicitly guard against capacity
+overflow for zero-sized types.
+
+Due to our current architecture, all this means is writing 3 guards, one in each
+method of RawVec.
+
+```rust,ignore
+impl<T> RawVec<T> {
+    fn new() -> Self {
+        unsafe {
+            // !0 is usize::MAX. This branch should be stripped at compile time.
+            let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
+
+            // heap::EMPTY doubles as "unallocated" and "zero-sized allocation"
+            RawVec { ptr: Unique::new(heap::EMPTY as *mut T), cap: cap }
+        }
+    }
+
+    fn grow(&mut self) {
+        unsafe {
+            let elem_size = mem::size_of::<T>();
+
+            // since we set the capacity to usize::MAX when elem_size is
+            // 0, getting to here necessarily means the Vec is overfull.
+            assert!(elem_size != 0, "capacity overflow");
+
+            let align = mem::align_of::<T>();
+
+            let (new_cap, ptr) = if self.cap == 0 {
+                let ptr = heap::allocate(elem_size, align);
+                (1, ptr)
+            } else {
+                let new_cap = 2 * self.cap;
+                let ptr = heap::reallocate(*self.ptr as *mut _,
+                                            self.cap * elem_size,
+                                            new_cap * elem_size,
+                                            align);
+                (new_cap, ptr)
+            };
+
+            // If allocate or reallocate fail, we'll get `null` back
+            if ptr.is_null() { oom() }
+
+            self.ptr = Unique::new(ptr as *mut _);
+            self.cap = new_cap;
+        }
+    }
+}
+
+impl<T> Drop for RawVec<T> {
+    fn drop(&mut self) {
+        let elem_size = mem::size_of::<T>();
+
+        // don't free zero-sized allocations, as they were never allocated.
+        if self.cap != 0 && elem_size != 0 {
+            let align = mem::align_of::<T>();
+
+            let num_bytes = elem_size * self.cap;
+            unsafe {
+                heap::deallocate(*self.ptr as *mut _, num_bytes, align);
+            }
+        }
+    }
+}
+```
+
+That's it. We support pushing and popping zero-sized types now. Our iterators
+(that aren't provided by slice Deref) are still busted, though.
+
+
+
+
+## Iterating Zero-Sized Types
+
+Zero-sized offsets are no-ops. This means that our current design will always
+initialize `start` and `end` as the same value, and our iterators will yield
+nothing. The current solution to this is to cast the pointers to integers,
+increment, and then cast them back:
+
+```rust,ignore
+impl<T> RawValIter<T> {
+    unsafe fn new(slice: &[T]) -> Self {
+        RawValIter {
+            start: slice.as_ptr(),
+            end: if mem::size_of::<T>() == 0 {
+                ((slice.as_ptr() as usize) + slice.len()) as *const _
+            } else if slice.len() == 0 {
+                slice.as_ptr()
+            } else {
+                slice.as_ptr().offset(slice.len() as isize)
+            }
+        }
+    }
+}
+```
+
+Now we have a different bug. Instead of our iterators not running at all, our
+iterators now run *forever*. We need to do the same trick in our iterator impls.
+Also, our size_hint computation code will divide by 0 for ZSTs. Since we'll
+basically be treating the two pointers as if they point to bytes, we'll just
+map size 0 to divide by 1.
+
+```rust,ignore
+impl<T> Iterator for RawValIter<T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> {
+        if self.start == self.end {
+            None
+        } else {
+            unsafe {
+                let result = ptr::read(self.start);
+                self.start = if mem::size_of::<T>() == 0 {
+                    (self.start as usize + 1) as *const _
+                } else {
+                    self.start.offset(1);
+                }
+                Some(result)
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let elem_size = mem::size_of::<T>();
+        let len = (self.end as usize - self.start as usize)
+                  / if elem_size == 0 { 1 } else { elem_size };
+        (len, Some(len))
+    }
+}
+
+impl<T> DoubleEndedIterator for RawValIter<T> {
+    fn next_back(&mut self) -> Option<T> {
+        if self.start == self.end {
+            None
+        } else {
+            unsafe {
+                self.end = if mem::size_of::<T>() == 0 {
+                    (self.end as usize - 1) as *const _
+                } else {
+                    self.end.offset(-1);
+                }
+                Some(ptr::read(self.end))
+            }
+        }
+    }
+}
+```
+
+And that's it. Iteration works!
diff --git a/src/doc/nomicon/vec.md b/src/doc/nomicon/vec.md
new file mode 100644
index 00000000000..63f83788c4b
--- /dev/null
+++ b/src/doc/nomicon/vec.md
@@ -0,0 +1,20 @@
+% Example: Implementing Vec
+
+To bring everything together, we're going to write `std::Vec` from scratch.
+Because all the best tools for writing unsafe code are unstable, this
+project will only work on nightly (as of Rust 1.2.0). With the exception of the
+allocator API, much of the unstable code we'll use is expected to be stabilized
+in a similar form as it is today.
+
+However we will generally try to avoid unstable code where possible. In
+particular we won't use any intrinsics that could make a code a little
+bit nicer or efficient because intrinsics are permanently unstable. Although
+many intrinsics *do* become stabilized elsewhere (`std::ptr` and `str::mem`
+consist of many intrinsics).
+
+Ultimately this means our implementation may not take advantage of all
+possible optimizations, though it will be by no means *naive*. We will
+definitely get into the weeds over nitty-gritty details, even
+when the problem doesn't *really* merit it.
+
+You wanted advanced. We're gonna go advanced.
diff --git a/src/doc/nomicon/working-with-unsafe.md b/src/doc/nomicon/working-with-unsafe.md
new file mode 100644
index 00000000000..b20dff72e1c
--- /dev/null
+++ b/src/doc/nomicon/working-with-unsafe.md
@@ -0,0 +1,119 @@
+% Working with Unsafe
+
+Rust generally only gives us the tools to talk about Unsafe Rust in a scoped and
+binary manner. Unfortunately, reality is significantly more complicated than
+that. For instance, consider the following toy function:
+
+```rust
+fn index(idx: usize, arr: &[u8]) -> Option<u8> {
+    if idx < arr.len() {
+        unsafe {
+            Some(*arr.get_unchecked(idx))
+        }
+    } else {
+        None
+    }
+}
+```
+
+Clearly, this function is safe. We check that the index is in bounds, and if it
+is, index into the array in an unchecked manner. But even in such a trivial
+function, the scope of the unsafe block is questionable. Consider changing the
+`<` to a `<=`:
+
+```rust
+fn index(idx: usize, arr: &[u8]) -> Option<u8> {
+    if idx <= arr.len() {
+        unsafe {
+            Some(*arr.get_unchecked(idx))
+        }
+    } else {
+        None
+    }
+}
+```
+
+This program is now unsound, and yet *we only modified safe code*. This is the
+fundamental problem of safety: it's non-local. The soundness of our unsafe
+operations necessarily depends on the state established by otherwise
+"safe" operations.
+
+Safety is modular in the sense that opting into unsafety doesn't require you
+to consider arbitrary other kinds of badness. For instance, doing an unchecked
+index into a slice doesn't mean you suddenly need to worry about the slice being
+null or containing uninitialized memory. Nothing fundamentally changes. However
+safety *isn't* modular in the sense that programs are inherently stateful and
+your unsafe operations may depend on arbitrary other state.
+
+Trickier than that is when we get into actual statefulness. Consider a simple
+implementation of `Vec`:
+
+```rust
+use std::ptr;
+
+// Note this definition is insufficient. See the section on implementing Vec.
+pub struct Vec<T> {
+    ptr: *mut T,
+    len: usize,
+    cap: usize,
+}
+
+// Note this implementation does not correctly handle zero-sized types.
+// We currently live in a nice imaginary world of only positive fixed-size
+// types.
+impl<T> Vec<T> {
+    pub fn push(&mut self, elem: T) {
+        if self.len == self.cap {
+            // not important for this example
+            self.reallocate();
+        }
+        unsafe {
+            ptr::write(self.ptr.offset(self.len as isize), elem);
+            self.len += 1;
+        }
+    }
+
+    # fn reallocate(&mut self) { }
+}
+
+# fn main() {}
+```
+
+This code is simple enough to reasonably audit and verify. Now consider
+adding the following method:
+
+```rust,ignore
+fn make_room(&mut self) {
+    // grow the capacity
+    self.cap += 1;
+}
+```
+
+This code is 100% Safe Rust but it is also completely unsound. Changing the
+capacity violates the invariants of Vec (that `cap` reflects the allocated space
+in the Vec). This is not something the rest of Vec can guard against. It *has*
+to trust the capacity field because there's no way to verify it.
+
+`unsafe` does more than pollute a whole function: it pollutes a whole *module*.
+Generally, the only bullet-proof way to limit the scope of unsafe code is at the
+module boundary with privacy.
+
+However this works *perfectly*. The existence of `make_room` is *not* a
+problem for the soundness of Vec because we didn't mark it as public. Only the
+module that defines this function can call it. Also, `make_room` directly
+accesses the private fields of Vec, so it can only be written in the same module
+as Vec.
+
+It is therefore possible for us to write a completely safe abstraction that
+relies on complex invariants. This is *critical* to the relationship between
+Safe Rust and Unsafe Rust. We have already seen that Unsafe code must trust
+*some* Safe code, but can't trust *generic* Safe code. It can't trust an
+arbitrary implementor of a trait or any function that was passed to it to be
+well-behaved in a way that safe code doesn't care about.
+
+However if unsafe code couldn't prevent client safe code from messing with its
+state in arbitrary ways, safety would be a lost cause. Thankfully, it *can*
+prevent arbitrary code from messing with critical state due to privacy.
+
+Safety lives!
+
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 9528871a774..5988d62bd79 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1199,8 +1199,8 @@ An example of an `enum` item and its use:
 
 ```
 enum Animal {
-  Dog,
-  Cat
+    Dog,
+    Cat,
 }
 
 let mut a: Animal = Animal::Dog;
diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md
index 85f0019276e..24686e772e3 100644
--- a/src/doc/trpl/SUMMARY.md
+++ b/src/doc/trpl/SUMMARY.md
@@ -26,8 +26,7 @@
     * [Primitive Types](primitive-types.md)
     * [Comments](comments.md)
     * [if](if.md)
-    * [for loops](for-loops.md)
-    * [while loops](while-loops.md)
+    * [Loops](loops.md)
     * [Ownership](ownership.md)
     * [References and Borrowing](references-and-borrowing.md)
     * [Lifetimes](lifetimes.md)
diff --git a/src/doc/trpl/choosing-your-guarantees.md b/src/doc/trpl/choosing-your-guarantees.md
index 1d3c76ce231..68812f342f1 100644
--- a/src/doc/trpl/choosing-your-guarantees.md
+++ b/src/doc/trpl/choosing-your-guarantees.md
@@ -42,7 +42,7 @@ allowed to share references to this by the regular borrowing rules, checked at c
 
 ## `&T` and `&mut T` 
 
-These are immutable and mutable references respectively. They follow the &lquo;read-write lock&rquo;
+These are immutable and mutable references respectively. They follow the &ldquo;read-write lock&rdquo;
 pattern, such that one may either have only one mutable reference to some data, or any number of
 immutable ones, but not both. This guarantee is enforced at compile time, and has no visible cost at
 runtime. In most cases these two pointer types suffice for sharing cheap references between sections
@@ -108,7 +108,7 @@ increment the inner reference count and return a copy of the `Rc<T>`.
 
 # Cell types
 
-&lquo;Cell&rquo;s provide interior mutability. In other words, they contain data which can be manipulated even
+`Cell`s provide interior mutability. In other words, they contain data which can be manipulated even
 if the type cannot be obtained in a mutable form (for example, when it is behind an `&`-ptr or
 `Rc<T>`).
 
@@ -127,7 +127,8 @@ If a field is wrapped in `Cell`, it's a nice indicator that the chunk of data is
 stay the same between the time you first read it and when you intend to use it.
 
 ```rust
-# use std::cell::Cell;
+use std::cell::Cell;
+
 let x = Cell::new(1);
 let y = &x;
 let z = &x;
@@ -185,7 +186,8 @@ any other borrows active when a mutable borrow is active. If the programmer atte
 borrow, the thread will panic.
 
 ```rust
-# use std::cell::RefCell;
+use std::cell::RefCell;
+
 let x = RefCell::new(vec![1,2,3,4]);
 {
     println!("{:?}", *x.borrow())
@@ -306,6 +308,7 @@ scope.
 
 Both of these provide safe shared mutability across threads, however they are prone to deadlocks.
 Some level of additional protocol safety can be obtained via the type system.
+
 #### Costs
 
 These use internal atomic-like types to maintain the locks, which are pretty costly (they can block
diff --git a/src/doc/trpl/compiler-plugins.md b/src/doc/trpl/compiler-plugins.md
index 127e097c34f..12adb9050d5 100644
--- a/src/doc/trpl/compiler-plugins.md
+++ b/src/doc/trpl/compiler-plugins.md
@@ -61,7 +61,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         ("I",    1)];
 
     let text = match args {
-        [TtToken(_, token::Ident(s, _))] => token::get_ident(s).to_string(),
+        [TtToken(_, token::Ident(s, _))] => s.to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
             return DummyResult::any(sp);
@@ -186,8 +186,7 @@ impl LintPass for Pass {
     }
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        let name = token::get_ident(it.ident);
-        if name.get() == "lintme" {
+        if it.ident.name == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
         }
     }
diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md
index 15c19ece48a..5a9569a69e6 100644
--- a/src/doc/trpl/concurrency.md
+++ b/src/doc/trpl/concurrency.md
@@ -115,7 +115,7 @@ languages. It will not compile:
 use std::thread;
 
 fn main() {
-    let mut data = vec![1u32, 2, 3];
+    let mut data = vec![1, 2, 3];
 
     for i in 0..3 {
         thread::spawn(move || {
@@ -153,7 +153,7 @@ use std::thread;
 use std::sync::Mutex;
 
 fn main() {
-    let mut data = Mutex::new(vec![1u32, 2, 3]);
+    let mut data = Mutex::new(vec![1, 2, 3]);
 
     for i in 0..3 {
         let data = data.lock().unwrap();
@@ -195,7 +195,7 @@ use std::sync::{Arc, Mutex};
 use std::thread;
 
 fn main() {
-    let data = Arc::new(Mutex::new(vec![1u32, 2, 3]));
+    let data = Arc::new(Mutex::new(vec![1, 2, 3]));
 
     for i in 0..3 {
         let data = data.clone();
@@ -217,7 +217,7 @@ thread more closely:
 # use std::sync::{Arc, Mutex};
 # use std::thread;
 # fn main() {
-#     let data = Arc::new(Mutex::new(vec![1u32, 2, 3]));
+#     let data = Arc::new(Mutex::new(vec![1, 2, 3]));
 #     for i in 0..3 {
 #         let data = data.clone();
 thread::spawn(move || {
@@ -255,7 +255,7 @@ use std::thread;
 use std::sync::mpsc;
 
 fn main() {
-    let data = Arc::new(Mutex::new(0u32));
+    let data = Arc::new(Mutex::new(0));
 
     let (tx, rx) = mpsc::channel();
 
@@ -293,7 +293,7 @@ fn main() {
         let tx = tx.clone();
 
         thread::spawn(move || {
-            let answer = 42u32;
+            let answer = 42;
 
             tx.send(answer);
         });
diff --git a/src/doc/trpl/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md
index 63fdef0760f..69890992065 100644
--- a/src/doc/trpl/crates-and-modules.md
+++ b/src/doc/trpl/crates-and-modules.md
@@ -355,6 +355,10 @@ Hello in English: Hello!
 Goodbye in English: Goodbye.
 ```
 
+`pub` also applies to `struct`s and their member fields. In keeping with Rust’s
+tendency toward safety, simply making a `struct` public won't automatically
+make its members public: you must mark the fields individually with `pub`.
+
 Now that our functions are public, we can use them. Great! However, typing out
 `phrases::english::greetings::hello()` is very long and repetitive. Rust has
 another keyword for importing names into the current scope, so that you can
@@ -517,9 +521,6 @@ of `foo` relative to where we are. If that’s prefixed with `::`, as in
 `::foo::bar()`, it refers to a different `foo`, an absolute path from your
 crate root.
 
-Also, note that we `pub use`d before we declared our `mod`s. Rust requires that
-`use` declarations go first.
-
 This will build and run:
 
 ```bash
diff --git a/src/doc/trpl/for-loops.md b/src/doc/trpl/for-loops.md
deleted file mode 100644
index 2866cee3a1a..00000000000
--- a/src/doc/trpl/for-loops.md
+++ /dev/null
@@ -1,85 +0,0 @@
-% for Loops
-
-The `for` loop is used to loop a particular number of times. Rust’s `for` loops
-work a bit differently than in other systems languages, however. Rust’s `for`
-loop doesn’t look like this “C-style” `for` loop:
-
-```c
-for (x = 0; x < 10; x++) {
-    printf( "%d\n", x );
-}
-```
-
-Instead, it looks like this:
-
-```rust
-for x in 0..10 {
-    println!("{}", x); // x: i32
-}
-```
-
-In slightly more abstract terms,
-
-```ignore
-for var in expression {
-    code
-}
-```
-
-The expression is an [iterator][iterator]. The iterator gives back a series of
-elements. Each element is one iteration of the loop. That value is then bound
-to the name `var`, which is valid for the loop body. Once the body is over, the
-next value is fetched from the iterator, and we loop another time. When there
-are no more values, the `for` loop is over.
-
-[iterator]: iterators.html
-
-In our example, `0..10` is an expression that takes a start and an end position,
-and gives an iterator over those values. The upper bound is exclusive, though,
-so our loop will print `0` through `9`, not `10`.
-
-Rust does not have the “C-style” `for` loop on purpose. Manually controlling
-each element of the loop is complicated and error prone, even for experienced C
-developers.
-
-# Enumerate
-
-When you need to keep track of how many times you already looped, you can use the `.enumerate()` function.
-
-## On ranges:
-
-```rust
-for (i,j) in (5..10).enumerate() {
-    println!("i = {} and j = {}", i, j);
-}
-```
-
-Outputs:
-
-```text
-i = 0 and j = 5
-i = 1 and j = 6
-i = 2 and j = 7
-i = 3 and j = 8
-i = 4 and j = 9
-```
-
-Don't forget to add the parentheses around the range.
-
-## On iterators:
-
-```rust
-# let lines = "hello\nworld".lines();
-for (linenumber, line) in lines.enumerate() {
-    println!("{}: {}", linenumber, line);
-}
-```
-
-Outputs:
-
-```text
-0: Content of line one
-1: Content of line two
-2: Content of line tree
-3: Content of line four
-```
diff --git a/src/doc/trpl/glossary.md b/src/doc/trpl/glossary.md
index c97da0e95b8..307aef80180 100644
--- a/src/doc/trpl/glossary.md
+++ b/src/doc/trpl/glossary.md
@@ -3,24 +3,12 @@
 Not every Rustacean has a background in systems programming, nor in computer
 science, so we've added explanations of terms that might be unfamiliar.
 
-### Arity
-
-Arity refers to the number of arguments a function or operation takes.
-
-```rust
-let x = (2, 3);
-let y = (4, 6);
-let z = (8, 2, 6);
-```
-
-In the example above `x` and `y` have arity 2. `z` has arity 3.
-
 ### Abstract Syntax Tree
 
-When a compiler is compiling your program, it does a number of different
-things. One of the things that it does is turn the text of your program into an
-‘abstract syntax tree’, or ‘AST’. This tree is a representation of the
-structure of your program. For example, `2 + 3` can be turned into a tree:
+When a compiler is compiling your program, it does a number of different things.
+One of the things that it does is turn the text of your program into an
+‘abstract syntax tree’, or ‘AST’. This tree is a representation of the structure
+of your program. For example, `2 + 3` can be turned into a tree:
 
 ```text
   +
@@ -37,3 +25,41 @@ And `2 + (3 * 4)` would look like this:
    / \
   3   4
 ```
+
+### Arity
+
+Arity refers to the number of arguments a function or operation takes.
+
+```rust
+let x = (2, 3);
+let y = (4, 6);
+let z = (8, 2, 6);
+```
+
+In the example above `x` and `y` have arity 2. `z` has arity 3.
+
+### Expression
+
+In computer programming, an expression is a combination of values, constants,
+variables, operators and functions that evaluate to a single value. For example,
+`2 + (3 * 4)` is an expression that returns the value 14. It is worth noting
+that expressions can have side-effects. For example, a function included in an
+expression might perform actions other than simply returning a value.
+
+### Expression-Oriented Language
+
+In early programming languages, [expressions][expression] and
+[statements][statement] were two separate syntactic categories: expressions had
+a value and statements did things. However, later languages blurred this
+distinction, allowing expressions to do things and statements to have a value.
+In an expression-oriented language, (nearly) every statement is an expression
+and therefore returns a value. Consequently, these expression statements can
+themselves form part of larger expressions.
+
+[expression]: glossary.html#expression
+[statement]: glossary.html#statement
+
+### Statement
+
+In computer programming, a statement is the smallest standalone element of a
+programming language that commands a computer to perform an action.
diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md
index 1784c253f7f..63a1c10f841 100644
--- a/src/doc/trpl/guessing-game.md
+++ b/src/doc/trpl/guessing-game.md
@@ -98,8 +98,8 @@ use std::io;
 
 We’ll need to take user input, and then print the result as output. As such, we
 need the `io` library from the standard library. Rust only imports a few things
-into every program, [the ‘prelude’][prelude]. If it’s not in the prelude,
-you’ll have to `use` it directly.
+by default into every program, [the ‘prelude’][prelude]. If it’s not in the
+prelude, you’ll have to `use` it directly.
 
 [prelude]: ../std/prelude/index.html
 
@@ -499,7 +499,7 @@ generator, which is local to the particular [thread][concurrency] of execution
 we’re in. Because we `use rand::Rng`’d above, it has a `gen_range()` method
 available. This method takes two arguments, and generates a number between
 them. It’s inclusive on the lower bound, but exclusive on the upper bound,
-so we need `1` and `101` to get a number between one and a hundred.
+so we need `1` and `101` to get a number ranging from one to a hundred.
 
 [concurrency]: concurrency.html
 
diff --git a/src/doc/trpl/hello-cargo.md b/src/doc/trpl/hello-cargo.md
index 8e479977887..4bd7de23f0c 100644
--- a/src/doc/trpl/hello-cargo.md
+++ b/src/doc/trpl/hello-cargo.md
@@ -8,13 +8,13 @@ so it is assumed that Rust projects will use Cargo from the beginning.
 [cratesio]: http://doc.crates.io
 
 Cargo manages three things: building your code, downloading the dependencies
-your code needs, and building those dependencies. At first, your
-program doesn’t have any dependencies, so we’ll only be using the first part of
-its functionality. Eventually, we’ll add more. Since we started off by using
-Cargo, it'll be easy to add later.
+your code needs, and building those dependencies. At first, your program doesn’t
+have any dependencies, so we’ll only be using the first part of its
+functionality. Eventually, we’ll add more. Since we started off by using Cargo,
+it'll be easy to add later.
 
-If you installed Rust via the official installers you will also have Cargo. If
-you installed Rust some other way, you may want to [check the Cargo
+If we installed Rust via the official installers we will also have Cargo. If we
+installed Rust some other way, we may want to [check the Cargo
 README][cargoreadme] for specific instructions about installing it.
 
 [cargoreadme]: https://github.com/rust-lang/cargo#installing-cargo-from-nightlies
@@ -23,20 +23,21 @@ README][cargoreadme] for specific instructions about installing it.
 
 Let’s convert Hello World to Cargo.
 
-To Cargo-ify our project, we need to do two things: Make a `Cargo.toml`
-configuration file, and put our source file in the right place. Let's
-do that part first:
+To Cargo-ify our project, we need to do three things: Make a `Cargo.toml`
+configuration file, put our source file in the right place, and get rid of the
+old executable (`main.exe` on Windows, `main` everywhere else). Let's do that part first:
 
 ```bash
 $ mkdir src
 $ mv main.rs src/main.rs
+$ rm main  # or main.exe on Windows
 ```
 
-Note that since we're creating an executable, we used `main.rs`. If we
-want to make a library instead, we should use `lib.rs`. This convention is required
-for Cargo to successfully compile our projects, but it can be overridden if we wish. 
-Custom file locations for the entry point can be specified
-with a [`[lib]` or `[[bin]]`][crates-custom] key in the TOML file.
+Note that since we're creating an executable, we retain `main.rs` as the source
+filename. If we want to make a library instead, we should use `lib.rs`. This
+convention is used by Cargo to successfully compile our projects, but it can be
+overridden if we wish. Custom file locations for the entry point can be
+specified with a [`[lib]` or `[[bin]]`][crates-custom] key in the TOML file.
 
 [crates-custom]: http://doc.crates.io/manifest.html#configuring-a-target
 
@@ -63,8 +64,8 @@ version = "0.0.1"
 authors = [ "Your name <you@example.com>" ]
 ```
 
-This file is in the [TOML][toml] format. TOML is similar to INI, but has some 
-extra goodies. According to the TOML docs, 
+This file is in the [TOML][toml] format. TOML is similar to INI, but has some
+extra goodies. According to the TOML docs,
 
 > TOML aims to be a minimal configuration file format that's easy to read due
 > to obvious semantics. TOML is designed to map unambiguously to a hash table.
@@ -73,7 +74,8 @@ extra goodies. According to the TOML docs,
 
 [toml]: https://github.com/toml-lang/toml
 
-Once you have this file in place, we should be ready to build! To do so, run:
+Once we have this file in place in our project's root directory, we should be
+ready to build! To do so, run:
 
 ```bash
 $ cargo build
diff --git a/src/doc/trpl/hello-world.md b/src/doc/trpl/hello-world.md
index eec6fe62f22..cd4326a28d8 100644
--- a/src/doc/trpl/hello-world.md
+++ b/src/doc/trpl/hello-world.md
@@ -111,10 +111,13 @@ string to the screen. Easy enough!
 
 [allocation]: the-stack-and-the-heap.html
 
-Finally, the line ends with a semicolon (`;`). Rust is an ‘expression oriented’
-language, which means that most things are expressions, rather than statements.
-The `;` is used to indicate that this expression is over, and the next one is
-ready to begin. Most lines of Rust code end with a `;`.
+Finally, the line ends with a semicolon (`;`). Rust is an [‘expression oriented’
+language][expression-oriented language], which means that most things are
+expressions, rather than statements. The `;` is used to indicate that this
+expression is over, and the next one is ready to begin. Most lines of Rust code
+end with a `;`.
+
+[expression-oriented language]: glossary.html#expression-oriented-language
 
 Finally, actually compiling and running our program. We can compile with our
 compiler, `rustc`, by passing it the name of our source file:
diff --git a/src/doc/trpl/intrinsics.md b/src/doc/trpl/intrinsics.md
index e0a8bb59e34..d1d836fe188 100644
--- a/src/doc/trpl/intrinsics.md
+++ b/src/doc/trpl/intrinsics.md
@@ -11,7 +11,7 @@ perform efficient pointer arithmetic, one would import those functions
 via a declaration like
 
 ```rust
-# #![feature(intrinsics)]
+#![feature(intrinsics)]
 # fn main() {}
 
 extern "rust-intrinsic" {
diff --git a/src/doc/trpl/lang-items.md b/src/doc/trpl/lang-items.md
index 8e7504c2f18..39de8920f09 100644
--- a/src/doc/trpl/lang-items.md
+++ b/src/doc/trpl/lang-items.md
@@ -54,6 +54,7 @@ fn main(argc: isize, argv: *const *const u8) -> isize {
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
 ```
 
 Note the use of `abort`: the `exchange_malloc` lang item is assumed to
diff --git a/src/doc/trpl/loops.md b/src/doc/trpl/loops.md
new file mode 100644
index 00000000000..a91fb8dadaf
--- /dev/null
+++ b/src/doc/trpl/loops.md
@@ -0,0 +1,209 @@
+% Loops
+
+Rust currently provides three approaches to performing some kind of iterative activity. They are: `loop`, `while` and `for`. Each approach has its own set of uses.
+
+## loop
+
+The infinite `loop` is the simplest form of loop available in Rust. Using the keyword `loop`, Rust provides a way to loop indefinitely until some terminating statement is reached. Rust's infinite `loop`s look like this:
+
+```rust,ignore
+loop {
+    println!("Loop forever!");
+}
+```
+
+## while
+
+Rust also has a `while` loop. It looks like this:
+
+```rust
+let mut x = 5; // mut x: i32
+let mut done = false; // mut done: bool
+
+while !done {
+    x += x - 3;
+
+    println!("{}", x);
+
+    if x % 5 == 0 {
+        done = true;
+    }
+}
+```
+
+`while` loops are the correct choice when you’re not sure how many times
+you need to loop.
+
+If you need an infinite loop, you may be tempted to write this:
+
+```rust,ignore
+while true {
+```
+
+However, `loop` is far better suited to handle this case:
+
+```rust,ignore
+loop {
+```
+
+Rust’s control-flow analysis treats this construct differently than a `while
+true`, since we know that it will always loop. In general, the more information
+we can give to the compiler, the better it can do with safety and code
+generation, so you should always prefer `loop` when you plan to loop
+infinitely.
+
+## for
+
+The `for` loop is used to loop a particular number of times. Rust’s `for` loops
+work a bit differently than in other systems languages, however. Rust’s `for`
+loop doesn’t look like this “C-style” `for` loop:
+
+```c
+for (x = 0; x < 10; x++) {
+    printf( "%d\n", x );
+}
+```
+
+Instead, it looks like this:
+
+```rust
+for x in 0..10 {
+    println!("{}", x); // x: i32
+}
+```
+
+In slightly more abstract terms,
+
+```ignore
+for var in expression {
+    code
+}
+```
+
+The expression is an [iterator][iterator]. The iterator gives back a series of
+elements. Each element is one iteration of the loop. That value is then bound
+to the name `var`, which is valid for the loop body. Once the body is over, the
+next value is fetched from the iterator, and we loop another time. When there
+are no more values, the `for` loop is over.
+
+[iterator]: iterators.html
+
+In our example, `0..10` is an expression that takes a start and an end position,
+and gives an iterator over those values. The upper bound is exclusive, though,
+so our loop will print `0` through `9`, not `10`.
+
+Rust does not have the “C-style” `for` loop on purpose. Manually controlling
+each element of the loop is complicated and error prone, even for experienced C
+developers.
+
+### Enumerate
+
+When you need to keep track of how many times you already looped, you can use the `.enumerate()` function.
+
+#### On ranges:
+
+```rust
+for (i,j) in (5..10).enumerate() {
+    println!("i = {} and j = {}", i, j);
+}
+```
+
+Outputs:
+
+```text
+i = 0 and j = 5
+i = 1 and j = 6
+i = 2 and j = 7
+i = 3 and j = 8
+i = 4 and j = 9
+```
+
+Don't forget to add the parentheses around the range.
+
+#### On iterators:
+
+```rust
+# let lines = "hello\nworld".lines();
+for (linenumber, line) in lines.enumerate() {
+    println!("{}: {}", linenumber, line);
+}
+```
+
+Outputs:
+
+```text
+0: Content of line one
+1: Content of line two
+2: Content of line tree
+3: Content of line four
+```
+
+## Ending iteration early
+
+Let’s take a look at that `while` loop we had earlier:
+
+```rust
+let mut x = 5;
+let mut done = false;
+
+while !done {
+    x += x - 3;
+
+    println!("{}", x);
+
+    if x % 5 == 0 {
+        done = true;
+    }
+}
+```
+
+We had to keep a dedicated `mut` boolean variable binding, `done`, to know
+when we should exit out of the loop. Rust has two keywords to help us with
+modifying iteration: `break` and `continue`.
+
+In this case, we can write the loop in a better way with `break`:
+
+```rust
+let mut x = 5;
+
+loop {
+    x += x - 3;
+
+    println!("{}", x);
+
+    if x % 5 == 0 { break; }
+}
+```
+
+We now loop forever with `loop` and use `break` to break out early. Issuing an explicit `return` statement will also serve to terminate the loop early.
+
+`continue` is similar, but instead of ending the loop, goes to the next
+iteration. This will only print the odd numbers:
+
+```rust
+for x in 0..10 {
+    if x % 2 == 0 { continue; }
+
+    println!("{}", x);
+}
+```
+
+## Loop labels
+
+You may also encounter situations where you have nested loops and need to
+specify which one your `break` or `continue` statement is for. Like most
+other languages, by default a `break` or `continue` will apply to innermost
+loop. In a sitation where you would like to a `break` or `continue` for one
+of the outer loops, you can use labels to specify which loop the `break` or
+ `continue` statement applies to. This will only print when both `x` and `y` are
+ odd:
+
+```rust
+'outer: for x in 0..10 {
+    'inner: for y in 0..10 {
+        if x % 2 == 0 { continue 'outer; } // continues the loop over x
+        if y % 2 == 0 { continue 'inner; } // continues the loop over y
+        println!("x: {}, y: {}", x, y);
+    }
+}
+```
diff --git a/src/doc/trpl/no-stdlib.md b/src/doc/trpl/no-stdlib.md
index 0a985334b5e..e530a9f1051 100644
--- a/src/doc/trpl/no-stdlib.md
+++ b/src/doc/trpl/no-stdlib.md
@@ -39,6 +39,7 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
 # // fn main() {} tricked you, rustdoc!
 ```
 
@@ -63,6 +64,7 @@ pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
 # // fn main() {} tricked you, rustdoc!
 ```
 
@@ -150,6 +152,7 @@ extern fn panic_fmt(args: &core::fmt::Arguments,
 
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
+# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
 # #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
 # fn main() {}
 ```
diff --git a/src/doc/trpl/patterns.md b/src/doc/trpl/patterns.md
index 9603eec7aca..1abd4ca6c21 100644
--- a/src/doc/trpl/patterns.md
+++ b/src/doc/trpl/patterns.md
@@ -112,26 +112,55 @@ match x {
 }
 ```
 
-# Ignoring variants
+# Ignoring bindings
 
-If you’re matching on an enum which has variants, you can use `..` to
-ignore the value and type in the variant:
+You can use `_` in a pattern to disregard the type and value.
+For example, here’s a `match` against a `Result<T, E>`:
 
 ```rust
-enum OptionalInt {
-    Value(i32),
+# let some_value: Result<i32, &'static str> = Err("There was an error");
+match some_value {
+    Ok(value) => println!("got a value: {}", value),
+    Err(_) => println!("an error occurred"),
+}
+```
+
+In the first arm, we bind the value inside the `Ok` variant to `value`. But
+in the `Err` arm, we use `_` to disregard the specific error, and just print
+a general error message.
+
+`_` is valid in any pattern that creates a binding. This can be useful to
+ignore parts of a larger structure:
+
+```rust
+fn coordinate() -> (i32, i32, i32) {
+    // generate and return some sort of triple tuple
+# (1, 2, 3)
+}
+
+let (x, _, z) = coordinate();
+```
+
+Here, we bind the first and last element of the tuple to `x` and `z`, but
+ignore the middle element.
+
+Similarly, you can use `..` in a pattern to disregard multiple values.
+
+```rust
+enum OptionalTuple {
+    Value(i32, i32, i32),
     Missing,
 }
 
-let x = OptionalInt::Value(5);
+let x = OptionalTuple::Value(5, -2, 3);
 
 match x {
-    OptionalInt::Value(..) => println!("Got an int!"),
-    OptionalInt::Missing => println!("No such luck."),
+    OptionalTuple::Value(..) => println!("Got a tuple!"),
+    OptionalTuple::Missing => println!("No such luck."),
 }
 ```
 
-This prints `Got an int!`.
+This prints `Got a tuple!`.
 
 # Guards
 
@@ -282,38 +311,6 @@ This ‘destructuring’ behavior works on any compound data type, like
 [tuples]: primitive-types.html#tuples
 [enums]: enums.html
 
-# Ignoring bindings
-
-You can use `_` in a pattern to disregard the value. For example, here’s a
-`match` against a `Result<T, E>`:
-
-```rust
-# let some_value: Result<i32, &'static str> = Err("There was an error");
-match some_value {
-    Ok(value) => println!("got a value: {}", value),
-    Err(_) => println!("an error occurred"),
-}
-```
-
-In the first arm, we bind the value inside the `Ok` variant to `value`. But
-in the `Err` arm, we use `_` to disregard the specific error, and just print
-a general error message.
-
-`_` is valid in any pattern that creates a binding. This can be useful to
-ignore parts of a larger structure:
-
-```rust
-fn coordinate() -> (i32, i32, i32) {
-    // generate and return some sort of triple tuple
-# (1, 2, 3)
-}
-
-let (x, _, z) = coordinate();
-```
-
-Here, we bind the first and last element of the tuple to `x` and `z`, but
-ignore the middle element.
-
 # Mix and Match
 
 Whew! That’s a lot of different ways to match things, and they can all be
diff --git a/src/doc/trpl/the-stack-and-the-heap.md b/src/doc/trpl/the-stack-and-the-heap.md
index ff81590cc03..cfab268a7c5 100644
--- a/src/doc/trpl/the-stack-and-the-heap.md
+++ b/src/doc/trpl/the-stack-and-the-heap.md
@@ -73,7 +73,7 @@ frame. But before we can show what happens when `foo()` is called, we need to
 visualize what’s going on with memory. Your operating system presents a view of
 memory to your program that’s pretty simple: a huge list of addresses, from 0
 to a large number, representing how much RAM your computer has. For example, if
-you have a gigabyte of RAM, your addresses go from `0` to `1,073,741,824`. That
+you have a gigabyte of RAM, your addresses go from `0` to `1,073,741,823`. That
 number comes from 2<sup>30</sup>, the number of bytes in a gigabyte.
 
 This memory is kind of like a giant array: addresses start at zero and go
@@ -551,7 +551,7 @@ is a great introduction.
 
 [wilson]: http://www.cs.northwestern.edu/~pdinda/icsclass/doc/dsa.pdf
 
-## Semantic impact 
+## Semantic impact
 
 Stack-allocation impacts the Rust language itself, and thus the developer’s
 mental model. The LIFO semantics is what drives how the Rust language handles
diff --git a/src/doc/trpl/while-loops.md b/src/doc/trpl/while-loops.md
deleted file mode 100644
index 124ebc7d69d..00000000000
--- a/src/doc/trpl/while-loops.md
+++ /dev/null
@@ -1,111 +0,0 @@
-% while Loops
-
-Rust also has a `while` loop. It looks like this:
-
-```rust
-let mut x = 5; // mut x: i32
-let mut done = false; // mut done: bool
-
-while !done {
-    x += x - 3;
-
-    println!("{}", x);
-
-    if x % 5 == 0 {
-        done = true;
-    }
-}
-```
-
-`while` loops are the correct choice when you’re not sure how many times
-you need to loop.
-
-If you need an infinite loop, you may be tempted to write this:
-
-```rust,ignore
-while true {
-```
-
-However, Rust has a dedicated keyword, `loop`, to handle this case:
-
-```rust,ignore
-loop {
-```
-
-Rust’s control-flow analysis treats this construct differently than a `while
-true`, since we know that it will always loop. In general, the more information
-we can give to the compiler, the better it can do with safety and code
-generation, so you should always prefer `loop` when you plan to loop
-infinitely.
-
-## Ending iteration early
-
-Let’s take a look at that `while` loop we had earlier:
-
-```rust
-let mut x = 5;
-let mut done = false;
-
-while !done {
-    x += x - 3;
-
-    println!("{}", x);
-
-    if x % 5 == 0 {
-        done = true;
-    }
-}
-```
-
-We had to keep a dedicated `mut` boolean variable binding, `done`, to know
-when we should exit out of the loop. Rust has two keywords to help us with
-modifying iteration: `break` and `continue`.
-
-In this case, we can write the loop in a better way with `break`:
-
-```rust
-let mut x = 5;
-
-loop {
-    x += x - 3;
-
-    println!("{}", x);
-
-    if x % 5 == 0 { break; }
-}
-```
-
-We now loop forever with `loop` and use `break` to break out early.
-
-`continue` is similar, but instead of ending the loop, goes to the next
-iteration. This will only print the odd numbers:
-
-```rust
-for x in 0..10 {
-    if x % 2 == 0 { continue; }
-
-    println!("{}", x);
-}
-```
-
-You may also encounter situations where you have nested loops and need to 
-specify which one your `break` or `continue` statement is for. Like most 
-other languages, by default a `break` or `continue` will apply to innermost 
-loop. In a sitation where you would like to a `break` or `continue` for one 
-of the outer loops, you can use labels to specify which loop the `break` or
- `continue` statement applies to. This will only print when both `x` and `y` are
- odd:
-
-```rust
-'outer: for x in 0..10 {
-    'inner: for y in 0..10 {
-        if x % 2 == 0 { continue 'outer; } // continues the loop over x
-        if y % 2 == 0 { continue 'inner; } // continues the loop over y
-        println!("x: {}, y: {}", x, y);
-    }
-}
-```
-
-Both `continue` and `break` are valid in both `while` loops and [`for` loops][for].
-
-[for]: for-loops.html
diff --git a/src/etc/ctags.rust b/src/etc/ctags.rust
index 59a2ae205cb..4397f290a5f 100644
--- a/src/etc/ctags.rust
+++ b/src/etc/ctags.rust
@@ -5,7 +5,7 @@
 --regex-Rust=/^[ \t]*(pub[ \t]+)?enum[ \t]+([a-zA-Z0-9_]+)/\2/g,enum,enumeration names/
 --regex-Rust=/^[ \t]*(pub[ \t]+)?struct[ \t]+([a-zA-Z0-9_]+)/\2/s,structure names/
 --regex-Rust=/^[ \t]*(pub[ \t]+)?mod[ \t]+([a-zA-Z0-9_]+)/\2/m,modules,module names/
---regex-Rust=/^[ \t]*(pub[ \t]+)?static[ \t]+([a-zA-Z0-9_]+)/\2/c,consts,static constants/
---regex-Rust=/^[ \t]*(pub[ \t]+)?trait[ \t]+([a-zA-Z0-9_]+)/\2/t,traits,traits/
---regex-Rust=/^[ \t]*(pub[ \t]+)?impl([ \t\n]*<[^>]*>)?[ \t]+(([a-zA-Z0-9_:]+)[ \t]*(<[^>]*>)?[ \t]+(for)[ \t]+)?([a-zA-Z0-9_]+)/\4 \6 \7/i,impls,trait implementations/
+--regex-Rust=/^[ \t]*(pub[ \t]+)?(static|const)[ \t]+(mut[ \t]+)?([a-zA-Z0-9_]+)/\4/c,consts,static constants/
+--regex-Rust=/^[ \t]*(pub[ \t]+)?(unsafe[ \t]+)?trait[ \t]+([a-zA-Z0-9_]+)/\3/t,traits,traits/
+--regex-Rust=/^[ \t]*(pub[ \t]+)?(unsafe[ \t]+)?impl([ \t\n]*<[^>]*>)?[ \t]+(([a-zA-Z0-9_:]+)[ \t]*(<[^>]*>)?[ \t]+(for)[ \t]+)?([a-zA-Z0-9_]+)/\5 \7 \8/i,impls,trait implementations/
 --regex-Rust=/^[ \t]*macro_rules![ \t]+([a-zA-Z0-9_]+)/\1/d,macros,macro definitions/
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 2a47fd29bd6..46b6a5722ea 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -78,16 +78,18 @@ use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
 use core::fmt;
 use core::cmp::Ordering;
 use core::mem::{align_of_val, size_of_val};
-use core::intrinsics::drop_in_place;
+use core::intrinsics::{drop_in_place, abort};
 use core::mem;
 use core::nonzero::NonZero;
 use core::ops::{Deref, CoerceUnsized};
 use core::ptr;
 use core::marker::Unsize;
 use core::hash::{Hash, Hasher};
-use core::usize;
+use core::{usize, isize};
 use heap::deallocate;
 
+const MAX_REFCOUNT: usize = (isize::MAX) as usize;
+
 /// An atomically reference counted wrapper for shared state.
 ///
 /// # Examples
@@ -200,7 +202,8 @@ impl<T: ?Sized> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(arc_weak)]
+    /// #![feature(arc_weak)]
+    ///
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -311,7 +314,21 @@ impl<T: ?Sized> Clone for Arc<T> {
         // another must already provide any required synchronization.
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
-        self.inner().strong.fetch_add(1, Relaxed);
+        let old_size = self.inner().strong.fetch_add(1, Relaxed);
+
+        // However we need to guard against massive refcounts in case someone
+        // is `mem::forget`ing Arcs. If we don't do this the count can overflow
+        // and users will use-after free. We racily saturate to `isize::MAX` on
+        // the assumption that there aren't ~2 billion threads incrementing
+        // the reference count at once. This branch will never be taken in
+        // any realistic program.
+        //
+        // We abort because such a program is incredibly degenerate, and we
+        // don't care to support it.
+        if old_size > MAX_REFCOUNT {
+            unsafe { abort(); }
+        }
+
         Arc { _ptr: self._ptr }
     }
 }
@@ -337,7 +354,8 @@ impl<T: Clone> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(arc_unique)]
+    /// #![feature(arc_unique)]
+    ///
     /// use std::sync::Arc;
     ///
     /// let mut five = Arc::new(5);
@@ -408,7 +426,8 @@ impl<T: ?Sized> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(arc_unique, alloc)]
+    /// #![feature(arc_unique, alloc)]
+    ///
     /// extern crate alloc;
     /// # fn main() {
     /// use alloc::arc::Arc;
@@ -555,7 +574,8 @@ impl<T: ?Sized> Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(arc_weak)]
+    /// #![feature(arc_weak)]
+    ///
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -599,7 +619,8 @@ impl<T: ?Sized> Clone for Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(arc_weak)]
+    /// #![feature(arc_weak)]
+    ///
     /// use std::sync::Arc;
     ///
     /// let weak_five = Arc::new(5).downgrade();
@@ -612,7 +633,13 @@ impl<T: ?Sized> Clone for Weak<T> {
         // fetch_add (ignoring the lock) because the weak count is only locked
         // where are *no other* weak pointers in existence. (So we can't be
         // running this code in that case).
-        self.inner().weak.fetch_add(1, Relaxed);
+        let old_size = self.inner().weak.fetch_add(1, Relaxed);
+
+        // See comments in Arc::clone() for why we do this (for mem::forget).
+        if old_size > MAX_REFCOUNT {
+            unsafe { abort(); }
+        }
+
         return Weak { _ptr: self._ptr }
     }
 }
@@ -626,7 +653,8 @@ impl<T: ?Sized> Drop for Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(arc_weak)]
+    /// #![feature(arc_weak)]
+    ///
     /// use std::sync::Arc;
     ///
     /// {
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index d5a177d3ee5..9420a88bade 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -56,6 +56,7 @@
 use core::prelude::*;
 
 use heap;
+use raw_vec::RawVec;
 
 use core::any::Any;
 use core::cmp::Ordering;
@@ -65,7 +66,7 @@ use core::marker::{self, Unsize};
 use core::mem;
 use core::ops::{CoerceUnsized, Deref, DerefMut};
 use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace};
-use core::ptr::Unique;
+use core::ptr::{self, Unique};
 use core::raw::{TraitObject};
 
 /// A value that represents the heap. This is the default place that the `box`
@@ -74,7 +75,8 @@ use core::raw::{TraitObject};
 /// The following two examples are equivalent:
 ///
 /// ```
-/// # #![feature(box_heap)]
+/// #![feature(box_heap)]
+///
 /// #![feature(box_syntax, placement_in_syntax)]
 /// use std::boxed::HEAP;
 ///
@@ -240,7 +242,8 @@ impl<T : ?Sized> Box<T> {
     ///
     /// # Examples
     /// ```
-    /// # #![feature(box_raw)]
+    /// #![feature(box_raw)]
+    ///
     /// let seventeen = Box::new(17u32);
     /// let raw = Box::into_raw(seventeen);
     /// let boxed_again = unsafe { Box::from_raw(raw) };
@@ -263,7 +266,8 @@ impl<T : ?Sized> Box<T> {
 ///
 /// # Examples
 /// ```
-/// # #![feature(box_raw)]
+/// #![feature(box_raw)]
+///
 /// use std::boxed;
 ///
 /// let seventeen = Box::new(17u32);
@@ -306,7 +310,8 @@ impl<T: Clone> Clone for Box<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(box_raw)]
+    /// #![feature(box_raw)]
+    ///
     /// let x = Box::new(5);
     /// let mut y = Box::new(10);
     ///
@@ -320,6 +325,19 @@ impl<T: Clone> Clone for Box<T> {
     }
 }
 
+
+#[stable(feature = "box_slice_clone", since = "1.3.0")]
+impl Clone for Box<str> {
+    fn clone(&self) -> Self {
+        let len = self.len();
+        let buf = RawVec::with_capacity(len);
+        unsafe {
+            ptr::copy_nonoverlapping(self.as_ptr(), buf.ptr(), len);
+            mem::transmute(buf.into_box()) // bytes to str ~magic
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
     #[inline]
@@ -514,3 +532,55 @@ impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
 }
 
 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
+
+#[stable(feature = "box_slice_clone", since = "1.3.0")]
+impl<T: Clone> Clone for Box<[T]> {
+    fn clone(&self) -> Self {
+        let mut new = BoxBuilder {
+            data: RawVec::with_capacity(self.len()),
+            len: 0
+        };
+
+        let mut target = new.data.ptr();
+
+        for item in self.iter() {
+            unsafe {
+                ptr::write(target, item.clone());
+                target = target.offset(1);
+            };
+
+            new.len += 1;
+        }
+
+        return unsafe { new.into_box() };
+
+        // Helper type for responding to panics correctly.
+        struct BoxBuilder<T> {
+            data: RawVec<T>,
+            len: usize,
+        }
+
+        impl<T> BoxBuilder<T> {
+            unsafe fn into_box(self) -> Box<[T]> {
+                let raw = ptr::read(&self.data);
+                mem::forget(self);
+                raw.into_box()
+            }
+        }
+
+        impl<T> Drop for BoxBuilder<T> {
+            fn drop(&mut self) {
+                let mut data = self.data.ptr();
+                let max = unsafe { data.offset(self.len as isize) };
+
+                while data != max {
+                    unsafe {
+                        ptr::read(data);
+                        data = data.offset(1);
+                    }
+                }
+            }
+        }
+    }
+}
+
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index fce327398e3..0e9b01e5c23 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -76,6 +76,7 @@
 #![feature(core)]
 #![feature(core_intrinsics)]
 #![feature(core_prelude)]
+#![feature(core_slice_ext)]
 #![feature(custom_attribute)]
 #![feature(fundamental)]
 #![feature(lang_items)]
@@ -91,6 +92,7 @@
 #![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(unsize)]
 #![feature(core_slice_ext)]
+#![feature(core_str_ext)]
 
 #![cfg_attr(test, feature(test, alloc, rustc_private, box_raw))]
 #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index d461eeea0b7..e4e3b3b209c 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -91,7 +91,8 @@
 //! documentation for more details on interior mutability.
 //!
 //! ```rust
-//! # #![feature(rc_weak)]
+//! #![feature(rc_weak)]
+//!
 //! use std::rc::Rc;
 //! use std::rc::Weak;
 //! use std::cell::RefCell;
@@ -160,7 +161,7 @@ use core::cell::Cell;
 use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{Hasher, Hash};
-use core::intrinsics::{assume, drop_in_place};
+use core::intrinsics::{assume, drop_in_place, abort};
 use core::marker::{self, Unsize};
 use core::mem::{self, align_of, size_of, align_of_val, size_of_val, forget};
 use core::nonzero::NonZero;
@@ -227,7 +228,8 @@ impl<T> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_unique)]
+    /// #![feature(rc_unique)]
+    ///
     /// use std::rc::Rc;
     ///
     /// let x = Rc::new(3);
@@ -262,7 +264,8 @@ impl<T: ?Sized> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_weak)]
+    /// #![feature(rc_weak)]
+    ///
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -292,7 +295,8 @@ impl<T: ?Sized> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_unique)]
+    /// #![feature(rc_unique)]
+    ///
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -313,7 +317,8 @@ impl<T: ?Sized> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_unique)]
+    /// #![feature(rc_unique)]
+    ///
     /// use std::rc::Rc;
     ///
     /// let mut x = Rc::new(3);
@@ -353,7 +358,8 @@ pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::strong_count(this) }
 /// # Examples
 ///
 /// ```
-/// # #![feature(rc_unique)]
+/// #![feature(rc_unique)]
+///
 /// use std::rc;
 /// use std::rc::Rc;
 ///
@@ -373,7 +379,8 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool { Rc::is_unique(rc) }
 /// # Examples
 ///
 /// ```
-/// # #![feature(rc_unique)]
+/// #![feature(rc_unique)]
+///
 /// use std::rc::{self, Rc};
 ///
 /// let x = Rc::new(3);
@@ -395,7 +402,8 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { Rc::try_unwrap(rc) }
 /// # Examples
 ///
 /// ```
-/// # #![feature(rc_unique)]
+/// #![feature(rc_unique)]
+///
 /// use std::rc::{self, Rc};
 ///
 /// let mut x = Rc::new(3);
@@ -419,7 +427,8 @@ impl<T: Clone> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_unique)]
+    /// #![feature(rc_unique)]
+    ///
     /// use std::rc::Rc;
     ///
     /// let mut five = Rc::new(5);
@@ -750,7 +759,8 @@ impl<T: ?Sized> Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_weak)]
+    /// #![feature(rc_weak)]
+    ///
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -778,7 +788,8 @@ impl<T: ?Sized> Drop for Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_weak)]
+    /// #![feature(rc_weak)]
+    ///
     /// use std::rc::Rc;
     ///
     /// {
@@ -825,7 +836,8 @@ impl<T: ?Sized> Clone for Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rc_weak)]
+    /// #![feature(rc_weak)]
+    ///
     /// use std::rc::Rc;
     ///
     /// let weak_five = Rc::new(5).downgrade();
@@ -846,6 +858,15 @@ impl<T: ?Sized+fmt::Debug> fmt::Debug for Weak<T> {
     }
 }
 
+// NOTE: We checked_add here to deal with mem::forget safety. In particular
+// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
+// you can free the allocation while outstanding Rcs (or Weaks) exist.
+// We abort because this is such a degenerate scenario that we don't care about
+// what happens -- no real program should ever experience this.
+//
+// This should have negligible overhead since you don't actually need to
+// clone these much in Rust thanks to ownership and move-semantics.
+
 #[doc(hidden)]
 trait RcBoxPtr<T: ?Sized> {
     fn inner(&self) -> &RcBox<T>;
@@ -854,7 +875,9 @@ trait RcBoxPtr<T: ?Sized> {
     fn strong(&self) -> usize { self.inner().strong.get() }
 
     #[inline]
-    fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }
+    fn inc_strong(&self) {
+        self.inner().strong.set(self.strong().checked_add(1).unwrap_or_else(|| unsafe { abort() }));
+    }
 
     #[inline]
     fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
@@ -863,7 +886,9 @@ trait RcBoxPtr<T: ?Sized> {
     fn weak(&self) -> usize { self.inner().weak.get() }
 
     #[inline]
-    fn inc_weak(&self) { self.inner().weak.set(self.weak() + 1); }
+    fn inc_weak(&self) {
+        self.inner().weak.set(self.weak().checked_add(1).unwrap_or_else(|| unsafe { abort() }));
+    }
 
     #[inline]
     fn dec_weak(&self) { self.inner().weak.set(self.weak() - 1); }
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index f6204173ed7..ddf61918947 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -216,7 +216,8 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![9, 1, 2, 7, 3, 2]);
     /// ```
@@ -236,7 +237,8 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
     ///
@@ -341,7 +343,8 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     /// let mut heap = BinaryHeap::from_vec(vec![1, 3]);
     ///
@@ -387,7 +390,8 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     /// let mut heap = BinaryHeap::new();
     /// heap.push(1);
@@ -419,7 +423,8 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     /// let mut heap = BinaryHeap::new();
     ///
@@ -445,7 +450,8 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4, 5, 6, 7]);
     /// let vec = heap.into_vec();
@@ -463,7 +469,8 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     ///
     /// let mut heap = BinaryHeap::from_vec(vec![1, 2, 4, 5, 7]);
@@ -724,7 +731,8 @@ impl<T: Ord> IntoIterator for BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
     ///
diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index 3a4cfbba65f..30f23e073f6 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -43,7 +43,8 @@
 //! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
 //!
 //! ```
-//! # #![feature(bitset, bitvec, range_inclusive, step_by)]
+//! #![feature(bitset, bitvec, range_inclusive, step_by)]
+//!
 //! use std::collections::{BitSet, BitVec};
 //! use std::iter;
 //!
@@ -139,7 +140,8 @@ const FALSE: &'static bool = &false;
 /// # Examples
 ///
 /// ```
-/// # #![feature(bitvec)]
+/// #![feature(bitvec)]
+///
 /// use std::collections::BitVec;
 ///
 /// let mut bv = BitVec::from_elem(10, false);
@@ -256,7 +258,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     /// let mut bv = BitVec::new();
     /// ```
@@ -271,7 +274,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_elem(10, false);
@@ -312,7 +316,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]);
@@ -355,7 +360,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 });
@@ -374,7 +380,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b01100000]);
@@ -407,7 +414,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(5, false);
@@ -430,7 +438,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
@@ -451,7 +460,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
@@ -480,7 +490,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
@@ -511,7 +522,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
@@ -542,7 +554,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
@@ -572,7 +585,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(5, true);
@@ -597,7 +611,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]);
@@ -614,7 +629,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec, append)]
+    /// #![feature(bitvec, append)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut a = BitVec::from_bytes(&[0b10000000]);
@@ -657,7 +673,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec, split_off)]
+    /// #![feature(bitvec, split_off)]
+    ///
     /// use std::collections::BitVec;
     /// let mut a = BitVec::new();
     /// a.push(true);
@@ -718,7 +735,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(10, false);
@@ -736,7 +754,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(10, false);
@@ -758,7 +777,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(3, true);
@@ -806,7 +826,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b10100000]);
@@ -827,7 +848,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_bytes(&[0b01001011]);
@@ -854,7 +876,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(3, false);
@@ -885,7 +908,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(3, false);
@@ -908,7 +932,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::new();
@@ -930,7 +955,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_bytes(&[0b01001011]);
@@ -981,7 +1007,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_bytes(&[0b01001001]);
@@ -1012,7 +1039,8 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitvec)]
+    /// #![feature(bitvec)]
+    ///
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::new();
@@ -1231,7 +1259,8 @@ impl<'a> IntoIterator for &'a BitVec {
 /// # Examples
 ///
 /// ```
-/// # #![feature(bitvec, bitset)]
+/// #![feature(bitvec, bitset)]
+///
 /// use std::collections::{BitSet, BitVec};
 ///
 /// // It's a regular set
@@ -1335,7 +1364,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1352,7 +1382,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::with_capacity(100);
@@ -1370,7 +1401,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let bv = BitVec::from_bytes(&[0b01100000]);
@@ -1392,7 +1424,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::with_capacity(100);
@@ -1414,7 +1447,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1441,7 +1475,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1462,7 +1497,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1483,7 +1519,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1530,7 +1567,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset)]
+    /// #![feature(bitset)]
+    ///
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1563,7 +1601,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let s = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01001010]));
@@ -1585,7 +1624,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1615,7 +1655,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1646,7 +1687,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1684,7 +1726,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1712,7 +1755,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1736,7 +1780,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1761,7 +1806,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1794,7 +1840,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec)]
+    /// #![feature(bitset, bitvec)]
+    ///
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1818,7 +1865,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec, append)]
+    /// #![feature(bitset, bitvec, append)]
+    ///
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let mut a = BitSet::new();
@@ -1849,7 +1897,8 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(bitset, bitvec, split_off)]
+    /// #![feature(bitset, bitvec, split_off)]
+    ///
     /// use std::collections::{BitSet, BitVec};
     /// let mut a = BitSet::new();
     /// a.insert(2);
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 27b10213ecd..a5a0d864572 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -1504,7 +1504,8 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(btree_range, collections_bound)]
+    /// #![feature(btree_range, collections_bound)]
+    ///
     /// use std::collections::BTreeMap;
     /// use std::collections::Bound::{Included, Unbounded};
     ///
@@ -1531,7 +1532,8 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(btree_range, collections_bound)]
+    /// #![feature(btree_range, collections_bound)]
+    ///
     /// use std::collections::BTreeMap;
     /// use std::collections::Bound::{Included, Excluded};
     ///
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 7c4cda305ad..596312e509e 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -141,7 +141,8 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(btree_range, collections_bound)]
+    /// #![feature(btree_range, collections_bound)]
+    ///
     /// use std::collections::BTreeSet;
     /// use std::collections::Bound::{Included, Unbounded};
     ///
diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs
index 7df259e9b36..b6c4905e41c 100644
--- a/src/libcollections/fmt.rs
+++ b/src/libcollections/fmt.rs
@@ -85,9 +85,9 @@
 //! format!("{a} {c} {b}", a="a", b='b', c=3);  // => "a 3 b"
 //! ```
 //!
-//! It is illegal to put positional parameters (those without names) after
-//! arguments which have names. Like with positional parameters, it is illegal
-//! to provide named parameters that are unused by the format string.
+//! It is not valid to put positional parameters (those without names) after
+//! arguments which have names. Like with positional parameters, it is not
+//! valid to provide named parameters that are unused by the format string.
 //!
 //! ## Argument types
 //!
@@ -103,8 +103,9 @@
 //! hexadecimal as well as an
 //! octal.
 //!
-//! There are various parameters which do require a particular type, however. Namely, the `{:.*}`
-//! syntax, which sets the number of numbers after the decimal in floating-point types:
+//! There are various parameters which do require a particular type, however.
+//! Namely, the `{:.*}` syntax, which sets the number of numbers after the
+//! decimal in floating-point types:
 //!
 //! ```
 //! let formatted_number = format!("{:.*}", 2, 1.234567);
@@ -112,10 +113,11 @@
 //! assert_eq!("1.23", formatted_number)
 //! ```
 //!
-//! If this syntax is used, then the number of characters to print precedes the actual object being
-//! formatted, and the number of characters must have the type `usize`. Although a `usize` can be
-//! printed with `{}`, it is illegal to reference an argument as such. For example this is another
-//! invalid format string:
+//! If this syntax is used, then the number of characters to print precedes the
+//! actual object being formatted, and the number of characters must have the
+//! type `usize`. Although a `usize` can be printed with `{}`, it is invalid to
+//! reference an argument as such. For example this is another invalid format
+//! string:
 //!
 //! ```text
 //! {:.*} {0}
@@ -172,7 +174,7 @@
 //! like:
 //!
 //! ```
-//! # #![feature(fmt_flags)]
+//! #![feature(fmt_flags)]
 //! use std::fmt;
 //!
 //! #[derive(Debug)]
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 1f948384992..ee7d2c4d23b 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -87,6 +87,7 @@ pub use enum_set::EnumSet;
 pub use vec_deque::VecDeque;
 pub use string::String;
 pub use vec::Vec;
+#[allow(deprecated)]
 pub use vec_map::VecMap;
 
 // Needed for the vec! macro
@@ -108,6 +109,7 @@ pub mod str;
 pub mod string;
 pub mod vec;
 pub mod vec_deque;
+#[allow(deprecated)]
 pub mod vec_map;
 
 #[unstable(feature = "bitvec", reason = "RFC 509")]
diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs
index a02cb44896a..32d6b3b95a4 100644
--- a/src/libcollections/linked_list.rs
+++ b/src/libcollections/linked_list.rs
@@ -784,7 +784,8 @@ impl<'a, A> IterMut<'a, A> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(linked_list_extras)]
+    /// #![feature(linked_list_extras)]
+    ///
     /// use std::collections::LinkedList;
     ///
     /// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect();
@@ -812,7 +813,8 @@ impl<'a, A> IterMut<'a, A> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(linked_list_extras)]
+    /// #![feature(linked_list_extras)]
+    ///
     /// use std::collections::LinkedList;
     ///
     /// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect();
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 00a0432956b..5ccf3973c28 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -887,7 +887,8 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```rust
-    /// # #![feature(permutations)]
+    /// #![feature(permutations)]
+    ///
     /// let v = [1, 2, 3];
     /// let mut perms = v.permutations();
     ///
@@ -899,7 +900,8 @@ impl<T> [T] {
     /// Iterating through permutations one by one.
     ///
     /// ```rust
-    /// # #![feature(permutations)]
+    /// #![feature(permutations)]
+    ///
     /// let v = [1, 2, 3];
     /// let mut perms = v.permutations();
     ///
@@ -924,7 +926,8 @@ impl<T> [T] {
     /// # Example
     ///
     /// ```rust
-    /// # #![feature(permutations)]
+    /// #![feature(permutations)]
+    ///
     /// let v: &mut [_] = &mut [0, 1, 2];
     /// v.next_permutation();
     /// let b: &mut [_] = &mut [0, 2, 1];
@@ -949,7 +952,8 @@ impl<T> [T] {
     /// # Example
     ///
     /// ```rust
-    /// # #![feature(permutations)]
+    /// #![feature(permutations)]
+    ///
     /// let v: &mut [_] = &mut [1, 0, 2];
     /// v.prev_permutation();
     /// let b: &mut [_] = &mut [0, 2, 1];
@@ -973,7 +977,8 @@ impl<T> [T] {
     /// # Example
     ///
     /// ```rust
-    /// # #![feature(clone_from_slice)]
+    /// #![feature(clone_from_slice)]
+    ///
     /// let mut dst = [0, 0, 0];
     /// let src = [1, 2];
     ///
@@ -1004,7 +1009,8 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```rust
-    /// # #![feature(move_from)]
+    /// #![feature(move_from)]
+    ///
     /// let mut a = [1, 2, 3, 4, 5];
     /// let b = vec![6, 7, 8];
     /// let num_moved = a.move_from(b, 0, 3);
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 58affdc4729..670d99bae40 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -425,6 +425,7 @@ impl str {
                  since = "1.0.0")]
     #[unstable(feature = "unicode",
                reason = "this functionality may only be provided by libunicode")]
+    #[inline]
     pub fn width(&self, is_cjk: bool) -> usize {
         UnicodeStr::width(self, is_cjk)
     }
@@ -441,7 +442,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_char)]
+    /// #![feature(str_char)]
+    ///
     /// let s = "Löwe 老虎 Léopard";
     /// assert!(s.is_char_boundary(0));
     /// // start of `老`
@@ -459,6 +461,7 @@ impl str {
                          with the existence of the char_indices iterator or \
                          this method may want to be replaced with checked \
                          slicing")]
+    #[inline]
     pub fn is_char_boundary(&self, index: usize) -> bool {
         core_str::StrExt::is_char_boundary(self, index)
     }
@@ -514,6 +517,7 @@ impl str {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
         core_str::StrExt::slice_unchecked(self, begin, end)
     }
@@ -522,6 +526,7 @@ impl str {
     ///
     /// Same as `slice_unchecked`, but works with `&mut str` instead of `&str`.
     #[unstable(feature = "str_slice_mut", reason = "recently added")]
+    #[inline]
     pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
         core_str::StrExt::slice_mut_unchecked(self, begin, end)
     }
@@ -545,7 +550,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(slice_chars)]
+    /// #![feature(slice_chars)]
+    ///
     /// let s = "Löwe 老虎 Léopard";
     ///
     /// assert_eq!(s.slice_chars(0, 4), "Löwe");
@@ -556,6 +562,7 @@ impl str {
     #[deprecated(since = "1.3.0",
                  reason = "can be implemented with char_indices and \
                            hasn't seen enough use to justify inclusion")]
+    #[inline]
     pub fn slice_chars(&self, begin: usize, end: usize) -> &str {
         core_str::StrExt::slice_chars(self, begin, end)
     }
@@ -576,7 +583,8 @@ impl str {
     /// done by `.chars()` or `.char_indices()`.
     ///
     /// ```
-    /// # #![feature(str_char, core)]
+    /// #![feature(str_char, core)]
+    ///
     /// use std::str::CharRange;
     ///
     /// let s = "中华Việt Nam";
@@ -608,6 +616,7 @@ impl str {
                reason = "often replaced by char_indices, this method may \
                          be removed in favor of just char_at() or eventually \
                          removed altogether")]
+    #[inline]
     pub fn char_range_at(&self, start: usize) -> CharRange {
         core_str::StrExt::char_range_at(self, start)
     }
@@ -633,7 +642,8 @@ impl str {
     /// done by `.chars().rev()` or `.char_indices()`.
     ///
     /// ```
-    /// # #![feature(str_char, core)]
+    /// #![feature(str_char, core)]
+    ///
     /// use std::str::CharRange;
     ///
     /// let s = "中华Việt Nam";
@@ -665,6 +675,7 @@ impl str {
                reason = "often replaced by char_indices, this method may \
                          be removed in favor of just char_at_reverse() or \
                          eventually removed altogether")]
+    #[inline]
     pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
         core_str::StrExt::char_range_at_reverse(self, start)
     }
@@ -679,7 +690,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_char)]
+    /// #![feature(str_char)]
+    ///
     /// let s = "abπc";
     /// assert_eq!(s.char_at(1), 'b');
     /// assert_eq!(s.char_at(2), 'π');
@@ -691,6 +703,7 @@ impl str {
                          future; it is normally replaced by chars/char_indices \
                          iterators or by getting the first char from a \
                          subslice")]
+    #[inline]
     pub fn char_at(&self, i: usize) -> char {
         core_str::StrExt::char_at(self, i)
     }
@@ -706,7 +719,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_char)]
+    /// #![feature(str_char)]
+    ///
     /// let s = "abπc";
     /// assert_eq!(s.char_at_reverse(1), 'a');
     /// assert_eq!(s.char_at_reverse(2), 'b');
@@ -716,6 +730,7 @@ impl str {
                reason = "see char_at for more details, but reverse semantics \
                          are also somewhat unclear, especially with which \
                          cases generate panics")]
+    #[inline]
     pub fn char_at_reverse(&self, i: usize) -> char {
         core_str::StrExt::char_at_reverse(self, i)
     }
@@ -733,7 +748,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_char)]
+    /// #![feature(str_char)]
+    ///
     /// let s = "Łódź"; // \u{141}o\u{301}dz\u{301}
     /// let (c, s1) = s.slice_shift_char().unwrap();
     ///
@@ -749,6 +765,7 @@ impl str {
                reason = "awaiting conventions about shifting and slices and \
                          may not be warranted with the existence of the chars \
                          and/or char_indices iterators")]
+    #[inline]
     pub fn slice_shift_char(&self) -> Option<(char, &str)> {
         core_str::StrExt::slice_shift_char(self)
     }
@@ -767,7 +784,8 @@ impl str {
     ///
     /// # Examples
     /// ```
-    /// # #![feature(str_split_at)]
+    /// #![feature(str_split_at)]
+    ///
     /// let s = "Löwe 老虎 Léopard";
     /// let first_space = s.find(' ').unwrap_or(s.len());
     /// let (a, b) = s.split_at(first_space);
@@ -810,6 +828,7 @@ impl str {
     ///     '\u{1f1e8}', '\u{1f1ed}', ' ', '한']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn chars(&self) -> Chars {
         core_str::StrExt::chars(self)
     }
@@ -825,6 +844,7 @@ impl str {
     /// assert_eq!(v, b);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn char_indices(&self) -> CharIndices {
         core_str::StrExt::char_indices(self)
     }
@@ -839,6 +859,7 @@ impl str {
     /// assert_eq!(v, b"bors".to_vec());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn bytes(&self) -> Bytes {
         core_str::StrExt::bytes(self)
     }
@@ -855,6 +876,7 @@ impl str {
     /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
     /// ```
     #[stable(feature = "split_whitespace", since = "1.1.0")]
+    #[inline]
     pub fn split_whitespace(&self) -> SplitWhitespace {
         UnicodeStr::split_whitespace(self)
     }
@@ -865,8 +887,9 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_words)]
-    /// # #![allow(deprecated)]
+    /// #![feature(str_words)]
+    /// #![allow(deprecated)]
+    ///
     /// let some_words = " Mary   had\ta\u{2009}little  \n\t lamb";
     /// let v: Vec<&str> = some_words.words().collect();
     ///
@@ -877,6 +900,7 @@ impl str {
     #[unstable(feature = "str_words",
                reason = "the precise algorithm to use is unclear")]
     #[allow(deprecated)]
+    #[inline]
     pub fn words(&self) -> Words {
         UnicodeStr::words(self)
     }
@@ -903,6 +927,7 @@ impl str {
     /// assert_eq!(v, ["foo", "bar", "", "baz"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn lines(&self) -> Lines {
         core_str::StrExt::lines(self)
     }
@@ -930,6 +955,7 @@ impl str {
     /// assert_eq!(v, ["foo", "bar", "", "baz"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn lines_any(&self) -> LinesAny {
         core_str::StrExt::lines_any(self)
     }
@@ -1021,7 +1047,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(unicode, core)]
+    /// #![feature(unicode, core)]
+    ///
     /// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
     /// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
     ///
@@ -1047,7 +1074,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(unicode, core)]
+    /// #![feature(unicode, core)]
+    ///
     /// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
     /// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
     ///
@@ -1585,7 +1613,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_match_indices)]
+    /// #![feature(str_match_indices)]
+    ///
     /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect();
     /// assert_eq!(v, [(0, 3), (6, 9), (12, 15)]);
     ///
@@ -1629,7 +1658,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(str_match_indices)]
+    /// #![feature(str_match_indices)]
+    ///
     /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
     /// assert_eq!(v, [(12, 15), (6, 9), (0, 3)]);
     ///
@@ -1659,7 +1689,8 @@ impl str {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(subslice_offset)]
+    /// #![feature(subslice_offset)]
+    ///
     /// let string = "a\nb\nc";
     /// let lines: Vec<&str> = string.lines().collect();
     ///
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index cc58952be60..0b441b42cdc 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -89,7 +89,8 @@ impl String {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// let s = String::from("hello");
     /// assert_eq!(&s[..], "hello");
     /// ```
@@ -702,7 +703,7 @@ impl String {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(drain)]
+    /// #![feature(drain)]
     ///
     /// let mut s = String::from("α is alpha, β is beta");
     /// let beta_offset = s.find('β').unwrap_or(s.len());
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index e9f3651d63b..96ad00597f8 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -112,6 +112,13 @@ use super::range::RangeArgument;
 /// assert_eq!(vec, [1, 2, 3, 4]);
 /// ```
 ///
+/// It can also initialize each element of a `Vec<T>` with a given value:
+///
+/// ```
+/// let vec = vec![0; 5];
+/// assert_eq!(vec, [0, 0, 0, 0, 0]);
+/// ```
+///
 /// Use a `Vec<T>` as an efficient stack:
 ///
 /// ```
@@ -574,7 +581,7 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// let mut vec = vec!(1, 2);
+    /// let mut vec = vec![1, 2];
     /// vec.push(3);
     /// assert_eq!(vec, [1, 2, 3]);
     /// ```
@@ -622,7 +629,8 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(append)]
+    /// #![feature(append)]
+    ///
     /// let mut vec = vec![1, 2, 3];
     /// let mut vec2 = vec![4, 5, 6];
     /// vec.append(&mut vec2);
@@ -661,7 +669,7 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(drain)]
+    /// #![feature(drain)]
     ///
     /// // Draining using `..` clears the whole vector.
     /// let mut v = vec![1, 2, 3];
@@ -759,7 +767,8 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(map_in_place)]
+    /// #![feature(map_in_place)]
+    ///
     /// let v = vec![0, 1, 2];
     /// let w = v.map_in_place(|i| i + 3);
     /// assert_eq!(&w[..], &[3, 4, 5]);
@@ -965,7 +974,8 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(split_off)]
+    /// #![feature(split_off)]
+    ///
     /// let mut vec = vec![1,2,3];
     /// let vec2 = vec.split_off(1);
     /// assert_eq!(vec, [1]);
@@ -1004,7 +1014,8 @@ impl<T: Clone> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vec_resize)]
+    /// #![feature(vec_resize)]
+    ///
     /// let mut vec = vec!["hello"];
     /// vec.resize(3, "world");
     /// assert_eq!(vec, ["hello", "world", "world"]);
@@ -1056,7 +1067,8 @@ impl<T: Clone> Vec<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vec_push_all)]
+    /// #![feature(vec_push_all)]
+    ///
     /// let mut vec = vec![1];
     /// vec.push_all(&[2, 3, 4]);
     /// assert_eq!(vec, [1, 2, 3, 4]);
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 7bdc10cfb64..c6d0d946ab0 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -231,7 +231,7 @@ impl<T> VecDeque<T> {
     /// buf.push_back(3);
     /// buf.push_back(4);
     /// buf.push_back(5);
-    /// assert_eq!(buf.get(1).unwrap(), &4);
+    /// assert_eq!(buf.get(1), Some(&4));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get(&self, index: usize) -> Option<&T> {
@@ -379,7 +379,8 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::with_capacity(15);
@@ -455,7 +456,8 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(deque_extras)]
+    /// #![feature(deque_extras)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -604,7 +606,8 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(drain)]
+    /// #![feature(drain)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut v = VecDeque::new();
@@ -847,17 +850,20 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(deque_extras)]
+    /// #![feature(deque_extras)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
     /// assert_eq!(buf.swap_back_remove(0), None);
-    /// buf.push_back(5);
-    /// buf.push_back(99);
-    /// buf.push_back(15);
-    /// buf.push_back(20);
-    /// buf.push_back(10);
-    /// assert_eq!(buf.swap_back_remove(1), Some(99));
+    /// buf.push_back(1);
+    /// buf.push_back(2);
+    /// buf.push_back(3);
+    ///
+    /// assert_eq!(buf.swap_back_remove(0), Some(1));
+    /// assert_eq!(buf.len(), 2);
+    /// assert_eq!(buf[0], 3);
+    /// assert_eq!(buf[1], 2);
     /// ```
     #[unstable(feature = "deque_extras",
                reason = "the naming of this function may be altered")]
@@ -881,17 +887,20 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(deque_extras)]
+    /// #![feature(deque_extras)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
     /// assert_eq!(buf.swap_front_remove(0), None);
-    /// buf.push_back(15);
-    /// buf.push_back(5);
-    /// buf.push_back(10);
-    /// buf.push_back(99);
-    /// buf.push_back(20);
-    /// assert_eq!(buf.swap_front_remove(3), Some(99));
+    /// buf.push_back(1);
+    /// buf.push_back(2);
+    /// buf.push_back(3);
+    ///
+    /// assert_eq!(buf.swap_front_remove(2), Some(3));
+    /// assert_eq!(buf.len(), 2);
+    /// assert_eq!(buf[0], 2);
+    /// assert_eq!(buf[1], 1);
     /// ```
     #[unstable(feature = "deque_extras",
                reason = "the naming of this function may be altered")]
@@ -915,7 +924,8 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     /// ```
-    /// # #![feature(collections)]
+    /// #![feature(collections)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -1123,12 +1133,12 @@ impl<T> VecDeque<T> {
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
-    /// buf.push_back(5);
-    /// buf.push_back(10);
-    /// buf.push_back(12);
-    /// buf.push_back(15);
-    /// buf.remove(2);
-    /// assert_eq!(Some(&15), buf.get(2));
+    /// buf.push_back(1);
+    /// buf.push_back(2);
+    /// buf.push_back(3);
+    ///
+    /// assert_eq!(buf.remove(1), Some(2));
+    /// assert_eq!(buf.get(1), Some(&3));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove(&mut self, index: usize) -> Option<T> {
@@ -1291,7 +1301,8 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(split_off)]
+    /// #![feature(split_off)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
@@ -1354,7 +1365,8 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(append)]
+    /// #![feature(append)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
@@ -1380,7 +1392,8 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vec_deque_retain)]
+    /// #![feature(vec_deque_retain)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -1415,7 +1428,8 @@ impl<T: Clone> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(deque_extras)]
+    /// #![feature(deque_extras)]
+    ///
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 685bb5dc4b4..a2d378a0faf 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -11,9 +11,12 @@
 //! A simple map based on a vector for small integer keys. Space requirements
 //! are O(highest integer key).
 
+#![deprecated(reason = "VecMap moved to crates.io as vec_map",
+              since = "1.3.0")]
+#![unstable(feature = "vecmap", reason = "deprecated")]
+#![allow(deprecated)]
+
 #![allow(missing_docs)]
-#![unstable(feature = "vecmap",
-            reason = "may not be stabilized in the standard library")]
 
 use self::Entry::*;
 
@@ -35,7 +38,8 @@ use vec::Vec;
 /// # Examples
 ///
 /// ```
-/// # #![feature(vecmap)]
+/// #![feature(vecmap)]
+///
 /// use std::collections::VecMap;
 ///
 /// let mut months = VecMap::new();
@@ -135,7 +139,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::new();
     /// ```
@@ -148,7 +153,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::with_capacity(10);
     /// ```
@@ -163,7 +169,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     /// let map: VecMap<String> = VecMap::with_capacity(10);
     /// assert!(map.capacity() >= 10);
@@ -183,7 +190,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::new();
     /// map.reserve_len(10);
@@ -208,7 +216,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::new();
     /// map.reserve_len_exact(10);
@@ -248,7 +257,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -277,7 +287,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -307,7 +318,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap, append)]
+    /// #![feature(vecmap, append)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -343,7 +355,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap, split_off)]
+    /// #![feature(vecmap, split_off)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -400,7 +413,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap, drain)]
+    /// #![feature(vecmap, drain)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -428,7 +442,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -446,7 +461,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -464,7 +480,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -480,7 +497,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -505,7 +523,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -524,7 +543,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -552,7 +572,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -578,7 +599,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -600,7 +622,8 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap, entry)]
+    /// #![feature(vecmap, entry)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut count: VecMap<u32> = VecMap::new();
@@ -778,7 +801,8 @@ impl<T> IntoIterator for VecMap<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vecmap)]
+    /// #![feature(vecmap)]
+    ///
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
index c0ab11380d9..65706b292c6 100644
--- a/src/libcollectionstest/slice.rs
+++ b/src/libcollectionstest/slice.rs
@@ -1270,6 +1270,59 @@ fn test_to_vec() {
     assert_eq!(ys, [1, 2, 3]);
 }
 
+#[test]
+fn test_box_slice_clone() {
+    let data = vec![vec![0, 1], vec![0], vec![1]];
+    let data2 = data.clone().into_boxed_slice().clone().to_vec();
+
+    assert_eq!(data, data2);
+}
+
+#[test]
+fn test_box_slice_clone_panics() {
+    use std::sync::Arc;
+    use std::sync::atomic::{AtomicUsize, Ordering};
+    use std::thread::spawn;
+
+    struct Canary {
+        count: Arc<AtomicUsize>,
+        panics: bool
+    }
+
+    impl Drop for Canary {
+        fn drop(&mut self) {
+            self.count.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+
+    impl Clone for Canary {
+        fn clone(&self) -> Self {
+            if self.panics { panic!() }
+
+            Canary {
+                count: self.count.clone(),
+                panics: self.panics
+            }
+        }
+    }
+
+    let drop_count = Arc::new(AtomicUsize::new(0));
+    let canary = Canary { count: drop_count.clone(), panics: false };
+    let panic = Canary { count: drop_count.clone(), panics: true };
+
+    spawn(move || {
+        // When xs is dropped, +5.
+        let xs = vec![canary.clone(), canary.clone(), canary.clone(),
+                      panic, canary].into_boxed_slice();
+
+        // When panic is cloned, +3.
+        xs.clone();
+    }).join().unwrap_err();
+
+    // Total = 8
+    assert_eq!(drop_count.load(Ordering::SeqCst), 8);
+}
+
 mod bench {
     use std::iter::repeat;
     use std::{mem, ptr};
diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs
index 5419c43ba09..4cccb29b41c 100644
--- a/src/libcollectionstest/str.rs
+++ b/src/libcollectionstest/str.rs
@@ -1766,6 +1766,14 @@ fn test_into_string() {
     assert_eq!(string.clone().into_boxed_slice().into_string(), string);
 }
 
+#[test]
+fn test_box_slice_clone() {
+    let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
+    let data2 = data.clone().into_boxed_slice().clone().into_string();
+
+    assert_eq!(data, data2);
+}
+
 mod pattern {
     use std::str::pattern::Pattern;
     use std::str::pattern::{Searcher, ReverseSearcher};
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index c6434e71957..53952cdc908 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -72,7 +72,7 @@
 
 use self::Ordering::*;
 
-use marker::Sync;
+use marker::{Send, Sync};
 
 use intrinsics;
 use cell::UnsafeCell;
@@ -134,6 +134,7 @@ impl<T> Default for AtomicPtr<T> {
     }
 }
 
+unsafe impl<T> Send for AtomicPtr<T> {}
 unsafe impl<T> Sync for AtomicPtr<T> {}
 
 /// Atomic memory orderings
@@ -145,7 +146,7 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
 /// "relaxed" atomics allow all reorderings.
 ///
 /// Rust's memory orderings are [the same as
-/// C++'s](http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync).
+/// LLVM's](http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations).
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Copy, Clone)]
 pub enum Ordering {
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 2c4ebeafc0b..c443270d5f4 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -221,7 +221,8 @@ impl<T:Copy> Cell<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(as_unsafe_cell)]
+    /// #![feature(as_unsafe_cell)]
+    ///
     /// use std::cell::Cell;
     ///
     /// let c = Cell::new(5);
@@ -589,7 +590,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
     /// # Example
     ///
     /// ```
-    /// # #![feature(cell_extras)]
+    /// #![feature(cell_extras)]
+    ///
     /// use std::cell::{RefCell, Ref};
     ///
     /// let c = RefCell::new((5, 'b'));
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 93542185eab..9d151abea78 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -383,7 +383,8 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// # Examples
 ///
 /// ```
-/// # #![feature(cmp_partial)]
+/// #![feature(cmp_partial)]
+///
 /// use std::cmp;
 ///
 /// assert_eq!(Some(1), cmp::partial_min(1, 2));
@@ -393,7 +394,8 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// When comparison is impossible:
 ///
 /// ```
-/// # #![feature(cmp_partial)]
+/// #![feature(cmp_partial)]
+///
 /// use std::cmp;
 ///
 /// let result = cmp::partial_min(std::f64::NAN, 1.0);
@@ -417,7 +419,8 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 /// # Examples
 ///
 /// ```
-/// # #![feature(cmp_partial)]
+/// #![feature(cmp_partial)]
+///
 /// use std::cmp;
 ///
 /// assert_eq!(Some(2), cmp::partial_max(1, 2));
@@ -427,7 +430,8 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 /// When comparison is impossible:
 ///
 /// ```
-/// # #![feature(cmp_partial)]
+/// #![feature(cmp_partial)]
+///
 /// use std::cmp;
 ///
 /// let result = cmp::partial_max(std::f64::NAN, 1.0);
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 8141916dd60..7cacc6af575 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -167,7 +167,8 @@ pub struct RadixFmt<T, R>(T, R);
 /// # Examples
 ///
 /// ```
-/// # #![feature(fmt_radix)]
+/// #![feature(fmt_radix)]
+///
 /// use std::fmt::radix;
 /// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
 /// ```
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index a660cf0cf2d..e35f380d06f 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -16,7 +16,8 @@
 //! # Examples
 //!
 //! ```rust
-//! # #![feature(hash_default)]
+//! #![feature(hash_default)]
+//!
 //! use std::hash::{hash, Hash, SipHasher};
 //!
 //! #[derive(Hash)]
@@ -36,7 +37,8 @@
 //! the trait `Hash`:
 //!
 //! ```rust
-//! # #![feature(hash_default)]
+//! #![feature(hash_default)]
+//!
 //! use std::hash::{hash, Hash, Hasher, SipHasher};
 //!
 //! struct Person {
@@ -89,8 +91,7 @@ pub trait Hash {
     fn hash<H: Hasher>(&self, state: &mut H);
 
     /// Feeds a slice of this type into the state provided.
-    #[unstable(feature = "hash_slice",
-               reason = "module was recently redesigned")]
+    #[stable(feature = "hash_slice", since = "1.3.0")]
     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized {
         for piece in data {
             piece.hash(state);
@@ -111,29 +112,29 @@ pub trait Hasher {
 
     /// Write a single `u8` into this hasher
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u8(&mut self, i: u8) { self.write(&[i]) }
     /// Write a single `u16` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u16(&mut self, i: u16) {
         self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
     }
     /// Write a single `u32` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u32(&mut self, i: u32) {
         self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
     }
     /// Write a single `u64` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_u64(&mut self, i: u64) {
         self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
     }
     /// Write a single `usize` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_usize(&mut self, i: usize) {
         if cfg!(target_pointer_width = "32") {
             self.write_u32(i as u32)
@@ -144,23 +145,23 @@ pub trait Hasher {
 
     /// Write a single `i8` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) }
     /// Write a single `i16` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) }
     /// Write a single `i32` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) }
     /// Write a single `i64` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) }
     /// Write a single `isize` into this hasher.
     #[inline]
-    #[unstable(feature = "hasher_write", reason = "module was recently redesigned")]
+    #[stable(feature = "hasher_write", since = "1.3.0")]
     fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) }
 }
 
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 4d8de0c85b6..2968d634544 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -824,7 +824,8 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(iter_min_max)]
+    /// #![feature(iter_min_max)]
+    ///
     /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
     ///
     /// let a: [i32; 0] = [];
@@ -898,7 +899,8 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(iter_cmp)]
+    /// #![feature(iter_cmp)]
+    ///
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
     /// ```
@@ -926,7 +928,8 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(iter_cmp)]
+    /// #![feature(iter_cmp)]
+    ///
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
     /// ```
@@ -1065,7 +1068,8 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(iter_arith)]
+    /// #![feature(iter_arith)]
+    ///
     /// let a = [1, 2, 3, 4, 5];
     /// let it = a.iter();
     /// assert_eq!(it.sum::<i32>(), 15);
@@ -1083,7 +1087,8 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(iter_arith)]
+    /// #![feature(iter_arith)]
+    ///
     /// fn factorial(n: u32) -> u32 {
     ///     (1..).take_while(|&i| i <= n).product()
     /// }
@@ -1367,7 +1372,8 @@ impl<T: Clone> MinMaxResult<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(iter_min_max)]
+    /// #![feature(iter_min_max)]
+    ///
     /// use std::iter::MinMaxResult::{self, NoElements, OneElement, MinMax};
     ///
     /// let r: MinMaxResult<i32> = NoElements;
@@ -2764,7 +2770,8 @@ impl<A: Step> ops::Range<A> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(step_by)]
+    /// #![feature(step_by)]
+    ///
     /// for i in (0..10).step_by(2) {
     ///     println!("{}", i);
     /// }
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index ef2a33c37dd..238644c4a26 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -65,6 +65,7 @@
 #![allow(raw_pointer_derive)]
 #![deny(missing_docs)]
 
+#![feature(associated_type_defaults)]
 #![feature(intrinsics)]
 #![feature(lang_items)]
 #![feature(on_unimplemented)]
@@ -157,21 +158,23 @@ pub mod fmt;
 // note: does not need to be public
 mod tuple;
 
+// A curious inner-module that's not exported that contains the bindings of core
+// so that compiler-expanded references to `core::$foo` can be resolved within
+// core itself.
+//
+// Note that no crate-defined macros require this module due to the existence of
+// the `$crate` meta variable, only those expansions defined in the compiler
+// require this. This is because the compiler doesn't currently know that it's
+// compiling the core library when it's compiling this library, so it expands
+// all references to `::core::$foo`
 #[doc(hidden)]
 mod core {
-    pub use intrinsics;
-    pub use panicking;
-    pub use fmt;
-    pub use clone;
-    pub use cmp;
-    pub use hash;
-    pub use marker;
-    pub use option;
-    pub use iter;
-}
-
-#[doc(hidden)]
-mod std {
-    // range syntax
-    pub use ops;
+    pub use intrinsics;     // derive(PartialOrd)
+    pub use fmt;            // format_args!
+    pub use clone;          // derive(Clone)
+    pub use cmp;            // derive(Ord)
+    pub use hash;           // derive(Hash)
+    pub use marker;         // derive(Copy)
+    pub use option;         // iterator protocol
+    pub use iter;           // iterator protocol
 }
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 14bb82dff7d..9f4d61a50d5 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -17,7 +17,7 @@ macro_rules! panic {
     );
     ($msg:expr) => ({
         static _MSG_FILE_LINE: (&'static str, &'static str, u32) = ($msg, file!(), line!());
-        ::core::panicking::panic(&_MSG_FILE_LINE)
+        $crate::panicking::panic(&_MSG_FILE_LINE)
     });
     ($fmt:expr, $($arg:tt)*) => ({
         // The leading _'s are to avoid dead code warnings if this is
@@ -25,7 +25,7 @@ macro_rules! panic {
         // insufficient, since the user may have
         // `#[forbid(dead_code)]` and which cannot be overridden.
         static _FILE_LINE: (&'static str, u32) = (file!(), line!());
-        ::core::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
+        $crate::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
     });
 }
 
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index dd60164a114..ebd6ba544e4 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -205,7 +205,7 @@ pub trait Copy : Clone {
 /// Any types with interior mutability must also use the `std::cell::UnsafeCell`
 /// wrapper around the value(s) which can be mutated when behind a `&`
 /// reference; not doing this is undefined behaviour (for example,
-/// `transmute`-ing from `&T` to `&mut T` is illegal).
+/// `transmute`-ing from `&T` to `&mut T` is invalid).
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 271d83201b1..7e63c8d71f9 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -253,20 +253,84 @@ pub unsafe fn dropped<T>() -> T {
     dropped_impl()
 }
 
-/// Creates an uninitialized value.
+/// Bypasses Rust's normal memory-initialization checks by pretending to
+/// produce a value of type T, while doing nothing at all.
 ///
-/// Care must be taken when using this function, if the type `T` has a destructor and the value
-/// falls out of scope (due to unwinding or returning) before being initialized, then the
-/// destructor will run on uninitialized data, likely leading to crashes.
+/// **This is incredibly dangerous, and should not be done lightly. Deeply
+/// consider initializing your memory with a default value instead.**
 ///
-/// This is useful for FFI functions sometimes, but should generally be avoided.
+/// This is useful for FFI functions and initializing arrays sometimes,
+/// but should generally be avoided.
+///
+/// # Undefined Behaviour
+///
+/// It is Undefined Behaviour to read uninitialized memory. Even just an
+/// uninitialized boolean. For instance, if you branch on the value of such
+/// a boolean your program may take one, both, or neither of the branches.
+///
+/// Note that this often also includes *writing* to the uninitialized value.
+/// Rust believes the value is initialized, and will therefore try to Drop
+/// the uninitialized value and its fields if you try to overwrite the memory
+/// in a normal manner. The only way to safely initialize an arbitrary
+/// uninitialized value is with one of the `ptr` functions: `write`, `copy`, or
+/// `copy_nonoverlapping`. This isn't necessary if `T` is a primitive
+/// or otherwise only contains types that don't implement Drop.
+///
+/// If this value *does* need some kind of Drop, it must be initialized before
+/// it goes out of scope (and therefore would be dropped). Note that this
+/// includes a `panic` occurring and unwinding the stack suddenly.
 ///
 /// # Examples
 ///
+/// Here's how to safely initialize an array of `Vec`s.
+///
 /// ```
 /// use std::mem;
+/// use std::ptr;
 ///
-/// let x: i32 = unsafe { mem::uninitialized() };
+/// // Only declare the array. This safely leaves it
+/// // uninitialized in a way that Rust will track for us.
+/// // However we can't initialize it element-by-element
+/// // safely, and we can't use the `[value; 1000]`
+/// // constructor because it only works with `Copy` data.
+/// let mut data: [Vec<u32>; 1000];
+///
+/// unsafe {
+///     // So we need to do this to initialize it.
+///     data = mem::uninitialized();
+///
+///     // DANGER ZONE: if anything panics or otherwise
+///     // incorrectly reads the array here, we will have
+///     // Undefined Behaviour.
+///
+///     // It's ok to mutably iterate the data, since this
+///     // doesn't involve reading it at all.
+///     // (ptr and len are statically known for arrays)
+///     for elem in &mut data[..] {
+///         // *elem = Vec::new() would try to drop the
+///         // uninitialized memory at `elem` -- bad!
+///         //
+///         // Vec::new doesn't allocate or do really
+///         // anything. It's only safe to call here
+///         // because we know it won't panic.
+///         ptr::write(elem, Vec::new());
+///     }
+///
+///     // SAFE ZONE: everything is initialized.
+/// }
+///
+/// println!("{:?}", &data[0]);
+/// ```
+///
+/// This example emphasizes exactly how delicate and dangerous doing this is.
+/// Note that the `vec!` macro *does* let you initialize every element with a
+/// value that is only `Clone`, so the following is semantically equivalent and
+/// vastly less dangerous, as long as you can live with an extra heap
+/// allocation:
+///
+/// ```
+/// let data: Vec<Vec<u32>> = vec![Vec::new(); 1000];
+/// println!("{:?}", &data[0]);
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index bfbb2ded078..ad891bf8fa6 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -479,8 +479,8 @@ macro_rules! int_impl {
         /// wrapping around at the boundary of the type.
         ///
         /// Such wrap-around never actually occurs mathematically;
-        /// implementation artifacts make `x % y` illegal for `MIN /
-        /// -1` on a signed type illegal (where `MIN` is the negative
+        /// implementation artifacts make `x % y` invalid for `MIN /
+        /// -1` on a signed type (where `MIN` is the negative
         /// minimal value). In such a case, this function returns `0`.
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[inline(always)]
@@ -1051,8 +1051,8 @@ macro_rules! uint_impl {
         /// wrapping around at the boundary of the type.
         ///
         /// Such wrap-around never actually occurs mathematically;
-        /// implementation artifacts make `x % y` illegal for `MIN /
-        /// -1` on a signed type illegal (where `MIN` is the negative
+        /// implementation artifacts make `x % y` invalid for `MIN /
+        /// -1` on a signed type (where `MIN` is the negative
         /// minimal value). In such a case, this function returns `0`.
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[inline(always)]
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 9ccba7ad78d..2235dc4af11 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -274,7 +274,8 @@ impl<T> Option<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(as_slice)]
+    /// #![feature(as_slice)]
+    ///
     /// let mut x = Some("Diamonds");
     /// {
     ///     let v = x.as_mut_slice();
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 6fed89547d4..116c1dfaa3e 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -20,7 +20,7 @@ use mem;
 use clone::Clone;
 use intrinsics;
 use ops::Deref;
-use core::fmt;
+use fmt;
 use option::Option::{self, Some, None};
 use marker::{PhantomData, Send, Sized, Sync};
 use nonzero::NonZero;
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index 43535ddd1d5..f0bac1bfef3 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -49,7 +49,8 @@ use mem;
 /// # Examples
 ///
 /// ```
-/// # #![feature(raw)]
+/// #![feature(raw)]
+///
 /// use std::raw::{self, Repr};
 ///
 /// let slice: &[u16] = &[1, 2, 3, 4];
@@ -98,7 +99,8 @@ impl<T> Clone for Slice<T> {
 /// # Examples
 ///
 /// ```
-/// # #![feature(raw)]
+/// #![feature(raw)]
+///
 /// use std::mem;
 /// use std::raw;
 ///
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 2b33b1f83d2..100cf0779b7 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -420,7 +420,8 @@ impl<T, E> Result<T, E> {
     /// Converts from `Result<T, E>` to `&mut [T]` (without copying)
     ///
     /// ```
-    /// # #![feature(as_slice)]
+    /// #![feature(as_slice)]
+    ///
     /// let mut x: Result<&str, u32> = Ok("Gold");
     /// {
     ///     let v = x.as_mut_slice();
diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs
index 7ecd08bea35..d0205fc9b12 100644
--- a/src/libcore/simd.rs
+++ b/src/libcore/simd.rs
@@ -19,7 +19,8 @@
 //! provided beyond this module.
 //!
 //! ```rust
-//! # #![feature(core_simd)]
+//! #![feature(core_simd)]
+//!
 //! fn main() {
 //!     use std::simd::f32x4;
 //!     let a = f32x4(40.0, 41.0, 42.0, 43.0);
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 9339f232e91..f765cdc54d8 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -300,11 +300,12 @@ impl<T> SliceExt for [T] {
 
     #[inline]
     fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+        let len = self.len();
+        let ptr = self.as_mut_ptr();
+        assert!(mid <= len);
         unsafe {
-            let self2: &mut [T] = mem::transmute_copy(&self);
-
-            (ops::IndexMut::index_mut(self, ops::RangeTo { end: mid } ),
-             ops::IndexMut::index_mut(self2, ops::RangeFrom { start: mid } ))
+            (from_raw_parts_mut(ptr, mid),
+             from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
         }
     }
 
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 707f7fcf2ab..2b3fc39fc8b 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -17,7 +17,7 @@
             reason = "API not fully fleshed out and ready to be stabilized")]
 
 use prelude::*;
-use core::cmp;
+use cmp;
 use usize;
 
 // Pattern
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 4d07573268a..69120b58181 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -47,7 +47,8 @@
 //! which is cyclic.
 //!
 //! ```rust
-//! # #![feature(rustc_private, core, into_cow)]
+//! #![feature(rustc_private, core, into_cow)]
+//!
 //! use std::borrow::IntoCow;
 //! use std::io::Write;
 //! use graphviz as dot;
@@ -149,7 +150,8 @@
 //! entity `&sube`).
 //!
 //! ```rust
-//! # #![feature(rustc_private, core, into_cow)]
+//! #![feature(rustc_private, core, into_cow)]
+//!
 //! use std::borrow::IntoCow;
 //! use std::io::Write;
 //! use graphviz as dot;
@@ -207,7 +209,8 @@
 //! Hasse-diagram for the subsets of the set `{x, y}`.
 //!
 //! ```rust
-//! # #![feature(rustc_private, core, into_cow)]
+//! #![feature(rustc_private, core, into_cow)]
+//!
 //! use std::borrow::IntoCow;
 //! use std::io::Write;
 //! use graphviz as dot;
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs
index c229df34ccf..8bd57a8cb1f 100644
--- a/src/liblibc/lib.rs
+++ b/src/liblibc/lib.rs
@@ -1002,14 +1002,14 @@ pub mod types {
             }
             pub mod posix01 {
                 use types::common::c95::{c_void};
-                use types::common::c99::{uint8_t, uint32_t, int32_t};
+                use types::common::c99::{uint32_t, int32_t};
                 use types::os::arch::c95::{c_long, time_t};
                 use types::os::arch::posix88::{dev_t, gid_t, ino_t};
                 use types::os::arch::posix88::{mode_t, off_t};
                 use types::os::arch::posix88::{uid_t};
 
                 pub type nlink_t = u16;
-                pub type blksize_t = i32;
+                pub type blksize_t = u32;
                 pub type blkcnt_t = i64;
                 pub type fflags_t = u32;
                 #[repr(C)]
@@ -1035,7 +1035,7 @@ pub mod types {
                     pub st_lspare: int32_t,
                     pub st_birthtime: time_t,
                     pub st_birthtime_nsec: c_long,
-                    pub __unused: [uint8_t; 2],
+                    pub __unused: [u8; 8],
                 }
 
                 #[repr(C)]
@@ -1096,14 +1096,14 @@ pub mod types {
             }
             pub mod posix01 {
                 use types::common::c95::{c_void};
-                use types::common::c99::{uint8_t, uint32_t, int32_t};
+                use types::common::c99::{uint32_t, int32_t};
                 use types::os::arch::c95::{c_long, time_t};
                 use types::os::arch::posix88::{dev_t, gid_t, ino_t};
                 use types::os::arch::posix88::{mode_t, off_t};
                 use types::os::arch::posix88::{uid_t};
 
                 pub type nlink_t = u16;
-                pub type blksize_t = i64;
+                pub type blksize_t = u32;
                 pub type blkcnt_t = i64;
                 pub type fflags_t = u32;
                 #[repr(C)]
@@ -1129,7 +1129,6 @@ pub mod types {
                     pub st_lspare: int32_t,
                     pub st_birthtime: time_t,
                     pub st_birthtime_nsec: c_long,
-                    pub __unused: [uint8_t; 2],
                 }
 
                 #[repr(C)]
diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs
index 10552791d8b..a193ffcc731 100644
--- a/src/librustc/ast_map/mod.rs
+++ b/src/librustc/ast_map/mod.rs
@@ -47,8 +47,7 @@ impl PathElem {
 
 impl fmt::Display for PathElem {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let slot = token::get_name(self.name());
-        write!(f, "{}", slot)
+        write!(f, "{}", self.name())
     }
 }
 
@@ -1073,18 +1072,18 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
             match ii.node {
                 ConstImplItem(..) => {
                     format!("assoc const {} in {}{}",
-                            token::get_ident(ii.ident),
+                            ii.ident,
                             map.path_to_string(id),
                             id_str)
                 }
                 MethodImplItem(..) => {
                     format!("method {} in {}{}",
-                            token::get_ident(ii.ident),
+                            ii.ident,
                             map.path_to_string(id), id_str)
                 }
                 TypeImplItem(_) => {
                     format!("assoc type {} in {}{}",
-                            token::get_ident(ii.ident),
+                            ii.ident,
                             map.path_to_string(id),
                             id_str)
                 }
@@ -1103,13 +1102,13 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
 
             format!("{} {} in {}{}",
                     kind,
-                    token::get_ident(ti.ident),
+                    ti.ident,
                     map.path_to_string(id),
                     id_str)
         }
         Some(NodeVariant(ref variant)) => {
             format!("variant {} in {}{}",
-                    token::get_ident(variant.node.name),
+                    variant.node.name,
                     map.path_to_string(id), id_str)
         }
         Some(NodeExpr(ref expr)) => {
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 768f792d269..9c2cdba0ae4 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -41,7 +41,7 @@ arms.
 "##,
 
 E0002: r##"
-This error indicates that an empty match expression is illegal because the type
+This error indicates that an empty match expression is invalid because the type
 it is matching on is non-empty (there exist values of this type). In safe code
 it is impossible to create an instance of an empty type, so empty match
 expressions are almost never desired.  This error is typically fixed by adding
@@ -1055,7 +1055,7 @@ because the `'static` lifetime is a special built-in lifetime name denoting
 the lifetime of the entire program, this is an error:
 
 ```
-// error, illegal lifetime parameter name `'static`
+// error, invalid lifetime parameter name `'static`
 fn foo<'static>(x: &'static str) { }
 ```
 "##,
@@ -1805,7 +1805,7 @@ For more information about `const fn`'s, see [RFC 911].
 E0394: r##"
 From [RFC 246]:
 
- > It is illegal for a static to reference another static by value. It is
+ > It is invalid for a static to reference another static by value. It is
  > required that all references be borrowed.
 
 [RFC 246]: https://github.com/rust-lang/rfcs/pull/246
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 6d29a1031c6..40ee023b7e8 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -34,6 +34,7 @@ use lint::builtin;
 use util::nodemap::FnvHashMap;
 
 use std::cell::RefCell;
+use std::cmp;
 use std::mem;
 use syntax::ast_util::IdVisitingOperation;
 use syntax::attr::AttrMetaMethods;
@@ -66,6 +67,9 @@ pub struct LintStore {
     /// Map of registered lint groups to what lints they expand to. The bool
     /// is true if the lint group was added by a plugin.
     lint_groups: FnvHashMap<&'static str, (Vec<LintId>, bool)>,
+
+    /// Maximum level a lint can be
+    lint_cap: Option<Level>,
 }
 
 /// The targed of the `by_name` map, which accounts for renaming/deprecation.
@@ -94,7 +98,10 @@ impl LintStore {
         }
     }
 
-    fn set_level(&mut self, lint: LintId, lvlsrc: LevelSource) {
+    fn set_level(&mut self, lint: LintId, mut lvlsrc: LevelSource) {
+        if let Some(cap) = self.lint_cap {
+            lvlsrc.0 = cmp::min(lvlsrc.0, cap);
+        }
         if lvlsrc.0 == Allow {
             self.levels.remove(&lint);
         } else {
@@ -109,6 +116,7 @@ impl LintStore {
             by_name: FnvHashMap(),
             levels: FnvHashMap(),
             lint_groups: FnvHashMap(),
+            lint_cap: None,
         }
     }
 
@@ -227,6 +235,13 @@ impl LintStore {
                 }
             }
         }
+
+        self.lint_cap = sess.opts.lint_cap;
+        if let Some(cap) = self.lint_cap {
+            for level in self.levels.iter_mut().map(|p| &mut (p.1).0) {
+                *level = cmp::min(*level, cap);
+            }
+        }
     }
 }
 
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 4ca34706309..623682a9cd5 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -33,7 +33,6 @@ use syntax::attr::AttrMetaMethods;
 use syntax::codemap::{self, Span, mk_sp, Pos};
 use syntax::parse;
 use syntax::parse::token::InternedString;
-use syntax::parse::token;
 use syntax::visit;
 use log;
 
@@ -181,19 +180,18 @@ impl<'a> CrateReader<'a> {
     fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> {
         match i.node {
             ast::ItemExternCrate(ref path_opt) => {
-                let ident = token::get_ident(i.ident);
                 debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
-                       ident, path_opt);
+                       i.ident, path_opt);
                 let name = match *path_opt {
                     Some(name) => {
-                        validate_crate_name(Some(self.sess), name.as_str(),
+                        validate_crate_name(Some(self.sess), &name.as_str(),
                                             Some(i.span));
-                        name.as_str().to_string()
+                        name.to_string()
                     }
-                    None => ident.to_string(),
+                    None => i.ident.to_string(),
                 };
                 Some(CrateInfo {
-                    ident: ident.to_string(),
+                    ident: i.ident.to_string(),
                     name: name,
                     id: i.id,
                     should_link: should_link(i),
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 55f0ef4fd57..b3ddd3869cb 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -299,15 +299,7 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: ast::DefId) -> DefLike {
         Constant  => {
             // Check whether we have an associated const item.
             if item_sort(item) == Some('C') {
-                // Check whether the associated const is from a trait or impl.
-                // See the comment for methods below.
-                let provenance = if reader::maybe_get_doc(
-                      item, tag_item_trait_parent_sort).is_some() {
-                    def::FromTrait(item_require_parent_item(cdata, item))
-                } else {
-                    def::FromImpl(item_require_parent_item(cdata, item))
-                };
-                DlDef(def::DefAssociatedConst(did, provenance))
+                DlDef(def::DefAssociatedConst(did))
             } else {
                 // Regular const item.
                 DlDef(def::DefConst(did))
@@ -319,18 +311,7 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: ast::DefId) -> DefLike {
         Fn        => DlDef(def::DefFn(did, false)),
         CtorFn    => DlDef(def::DefFn(did, true)),
         Method | StaticMethod => {
-            // def_static_method carries an optional field of its enclosing
-            // trait or enclosing impl (if this is an inherent static method).
-            // So we need to detect whether this is in a trait or not, which
-            // we do through the mildly hacky way of checking whether there is
-            // a trait_parent_sort.
-            let provenance = if reader::maybe_get_doc(
-                  item, tag_item_trait_parent_sort).is_some() {
-                def::FromTrait(item_require_parent_item(cdata, item))
-            } else {
-                def::FromImpl(item_require_parent_item(cdata, item))
-            };
-            DlDef(def::DefMethod(did, provenance))
+            DlDef(def::DefMethod(did))
         }
         Type => {
             if item_sort(item) == Some('t') {
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 987b6ad5b72..5167014d4ab 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -40,7 +40,6 @@ use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::SpanHandler;
 use syntax::parse::token::special_idents;
-use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::visit::Visitor;
@@ -83,11 +82,11 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
 }
 
 fn encode_name(rbml_w: &mut Encoder, name: ast::Name) {
-    rbml_w.wr_tagged_str(tag_paths_data_name, &token::get_name(name));
+    rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str());
 }
 
 fn encode_impl_type_basename(rbml_w: &mut Encoder, name: ast::Name) {
-    rbml_w.wr_tagged_str(tag_item_impl_type_basename, &token::get_name(name));
+    rbml_w.wr_tagged_str(tag_item_impl_type_basename, &name.as_str());
 }
 
 fn encode_def_id(rbml_w: &mut Encoder, id: DefId) {
@@ -349,7 +348,7 @@ fn encode_path<PI: Iterator<Item=PathElem>>(rbml_w: &mut Encoder, path: PI) {
             ast_map::PathMod(_) => tag_path_elem_mod,
             ast_map::PathName(_) => tag_path_elem_name
         };
-        rbml_w.wr_tagged_str(tag, &token::get_name(pe.name()));
+        rbml_w.wr_tagged_str(tag, &pe.name().as_str());
     }
     rbml_w.end_tag();
 }
@@ -359,13 +358,13 @@ fn encode_reexported_static_method(rbml_w: &mut Encoder,
                                    method_def_id: DefId,
                                    method_name: ast::Name) {
     debug!("(encode reexported static method) {}::{}",
-            exp.name, token::get_name(method_name));
+            exp.name, method_name);
     rbml_w.start_tag(tag_items_data_item_reexport);
     rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id,
                          def_to_u64(method_def_id));
     rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
                          &format!("{}::{}", exp.name,
-                                            token::get_name(method_name)));
+                                            method_name));
     rbml_w.end_tag();
 }
 
@@ -499,15 +498,12 @@ fn encode_reexports(ecx: &EncodeContext,
                 rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id,
                                      def_to_u64(exp.def_id));
                 rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
-                                     exp.name.as_str());
+                                     &exp.name.as_str());
                 rbml_w.end_tag();
                 encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
             }
-        }
-        None => {
-            debug!("(encoding info for module) found no reexports for {}",
-                   id);
-        }
+        },
+        None => debug!("(encoding info for module) found no reexports for {}", id),
     }
 }
 
@@ -539,7 +535,7 @@ fn encode_info_for_mod(ecx: &EncodeContext,
         if let ast::ItemImpl(..) = item.node {
             let (ident, did) = (item.ident, item.id);
             debug!("(encoding info for module) ... encoding impl {} ({}/{})",
-                   token::get_ident(ident),
+                   ident,
                    did, ecx.tcx.map.node_to_string(did));
 
             rbml_w.wr_tagged_u64(tag_mod_impl, def_to_u64(local_def(did)));
@@ -656,7 +652,7 @@ fn encode_info_for_struct(ecx: &EncodeContext,
         });
         rbml_w.start_tag(tag_items_data_item);
         debug!("encode_info_for_struct: doing {} {}",
-               token::get_name(nm), id);
+               nm, id);
         encode_struct_field_family(rbml_w, field.vis);
         encode_name(rbml_w, nm);
         encode_bounds_and_type_for_item(rbml_w, ecx, id);
@@ -816,7 +812,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext,
                                     impl_item_opt: Option<&ast::ImplItem>) {
     debug!("encode_info_for_associated_const({:?},{:?})",
            associated_const.def_id,
-           token::get_name(associated_const.name));
+           associated_const.name);
 
     rbml_w.start_tag(tag_items_data_item);
 
@@ -854,7 +850,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                     impl_item_opt: Option<&ast::ImplItem>) {
 
     debug!("encode_info_for_method: {:?} {:?}", m.def_id,
-           token::get_name(m.name));
+           m.name);
     rbml_w.start_tag(tag_items_data_item);
 
     encode_method_ty_fields(ecx, rbml_w, m);
@@ -899,7 +895,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                              impl_item_opt: Option<&ast::ImplItem>) {
     debug!("encode_info_for_associated_type({:?},{:?})",
            associated_type.def_id,
-           token::get_name(associated_type.name));
+           associated_type.name);
 
     rbml_w.start_tag(tag_items_data_item);
 
@@ -937,7 +933,7 @@ fn encode_method_argument_names(rbml_w: &mut Encoder,
     for arg in &decl.inputs {
         let tag = tag_method_argument_name;
         if let ast::PatIdent(_, ref path1, _) = arg.pat.node {
-            let name = token::get_name(path1.node.name);
+            let name = path1.node.name.as_str();
             rbml_w.wr_tagged_bytes(tag, name.as_bytes());
         } else {
             rbml_w.wr_tagged_bytes(tag, &[]);
@@ -1562,7 +1558,7 @@ fn my_visit_foreign_item(ni: &ast::ForeignItem,
                          index: &mut Vec<entry<i64>>) {
     debug!("writing foreign item {}::{}",
             ecx.tcx.map.path_to_string(ni.id),
-            token::get_ident(ni.ident));
+            ni.ident);
 
     let abi = ecx.tcx.map.get_foreign_abi(ni.id);
     ecx.tcx.map.with_path(ni.id, |path| {
@@ -1748,7 +1744,7 @@ fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
 fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
     rbml_w.start_tag(tag_associated_type_names);
     for &name in names {
-        rbml_w.wr_tagged_str(tag_associated_type_name, &token::get_name(name));
+        rbml_w.wr_tagged_str(tag_associated_type_name, &name.as_str());
     }
     rbml_w.end_tag();
 }
diff --git a/src/librustc/metadata/macro_import.rs b/src/librustc/metadata/macro_import.rs
index 8606cbc53d5..08975bab600 100644
--- a/src/librustc/metadata/macro_import.rs
+++ b/src/librustc/metadata/macro_import.rs
@@ -149,8 +149,7 @@ impl<'a> MacroLoader<'a> {
         let mut seen = HashSet::new();
 
         for mut def in macros {
-            let name = token::get_ident(def.ident);
-            seen.insert(name.clone());
+            let name = def.ident.name.as_str();
 
             def.use_locally = match import.as_ref() {
                 None => true,
@@ -161,18 +160,19 @@ impl<'a> MacroLoader<'a> {
                                                               "allow_internal_unstable");
             debug!("load_macros: loaded: {:?}", def);
             self.macros.push(def);
+            seen.insert(name);
         }
 
         if let Some(sel) = import.as_ref() {
             for (name, span) in sel {
-                if !seen.contains(name) {
+                if !seen.contains(&name) {
                     self.sess.span_err(*span, "imported macro not found");
                 }
             }
         }
 
         for (name, span) in &reexport {
-            if !seen.contains(name) {
+            if !seen.contains(&name) {
                 self.sess.span_err(*span, "reexported macro not found");
             }
         }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 597401daccf..1831c3518d7 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -26,7 +26,6 @@ use util::nodemap::FnvHashMap;
 use syntax::abi::Abi;
 use syntax::ast;
 use syntax::diagnostic::SpanHandler;
-use syntax::parse::token;
 
 use rbml::writer::Encoder;
 
@@ -136,7 +135,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
             cx.diag.handler().bug("cannot encode inference variable types");
         }
         ty::TyParam(ParamTy {space, idx, name}) => {
-            mywrite!(w, "p[{}|{}|{}]", idx, space.to_uint(), token::get_name(name))
+            mywrite!(w, "p[{}|{}|{}]", idx, space.to_uint(), name)
         }
         ty::TyStruct(def, substs) => {
             mywrite!(w, "a[{}|", (cx.ds)(def));
@@ -155,7 +154,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
         ty::TyProjection(ref data) => {
             mywrite!(w, "P[");
             enc_trait_ref(w, cx, data.trait_ref);
-            mywrite!(w, "{}]", token::get_name(data.item_name));
+            mywrite!(w, "{}]", data.item_name);
         }
         ty::TyError => {
             mywrite!(w, "e");
@@ -251,7 +250,7 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
                      data.param_id,
                      data.space.to_uint(),
                      data.index,
-                     token::get_name(data.name));
+                     data.name);
         }
         ty::ReFree(ref fr) => {
             mywrite!(w, "f[");
@@ -302,7 +301,7 @@ fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
         ty::BrNamed(d, name) => {
             mywrite!(w, "[{}|{}]",
                      (cx.ds)(d),
-                     token::get_name(name));
+                     name);
         }
         ty::BrFresh(id) => {
             mywrite!(w, "f{}|", id);
@@ -410,7 +409,7 @@ pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,
 pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                                     v: &ty::TypeParameterDef<'tcx>) {
     mywrite!(w, "{}:{}|{}|{}|{}|",
-             token::get_name(v.name), (cx.ds)(v.def_id),
+             v.name, (cx.ds)(v.def_id),
              v.space.to_uint(), v.index, (cx.ds)(v.default_def_id));
     enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
     enc_object_lifetime_default(w, cx, v.object_lifetime_default);
@@ -465,6 +464,6 @@ fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder,
                                       cx: &ctxt<'a, 'tcx>,
                                       data: &ty::ProjectionPredicate<'tcx>) {
     enc_trait_ref(w, cx, data.projection_ty.trait_ref);
-    mywrite!(w, "{}|", token::get_name(data.projection_ty.item_name));
+    mywrite!(w, "{}|", data.projection_ty.item_name);
     enc_ty(w, cx, data.ty);
 }
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 7c76f4fe289..5c3b0a1c2d2 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -34,7 +34,6 @@ use middle::ty::{self, Ty};
 use syntax::{ast, ast_util, codemap, fold};
 use syntax::codemap::Span;
 use syntax::fold::Folder;
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax;
 
@@ -156,10 +155,10 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
             ast::IITraitItem(_, ref ti) => ti.ident,
             ast::IIImplItem(_, ref ii) => ii.ident
         };
-        debug!("Fn named: {}", token::get_ident(ident));
+        debug!("Fn named: {}", ident);
         debug!("< Decoded inlined fn: {}::{}",
                path_as_str.unwrap(),
-               token::get_ident(ident));
+               ident);
         region::resolve_inlined_item(&tcx.sess, &tcx.region_maps, ii);
         decode_side_tables(dcx, ast_doc);
         match *ii {
@@ -445,9 +444,7 @@ impl tr for def::Def {
     fn tr(&self, dcx: &DecodeContext) -> def::Def {
         match *self {
           def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
-          def::DefMethod(did, p) => {
-            def::DefMethod(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
-          }
+          def::DefMethod(did) => def::DefMethod(did.tr(dcx)),
           def::DefSelfTy(opt_did, impl_ids) => { def::DefSelfTy(opt_did.map(|did| did.tr(dcx)),
                                                                 impl_ids.map(|(nid1, nid2)| {
                                                                     (dcx.tr_id(nid1),
@@ -457,9 +454,7 @@ impl tr for def::Def {
           def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
           def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
           def::DefConst(did) => { def::DefConst(did.tr(dcx)) }
-          def::DefAssociatedConst(did, p) => {
-              def::DefAssociatedConst(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
-          }
+          def::DefAssociatedConst(did) => def::DefAssociatedConst(did.tr(dcx)),
           def::DefLocal(nid) => { def::DefLocal(dcx.tr_id(nid)) }
           def::DefVariant(e_did, v_did, is_s) => {
             def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index baaf6b6a040..9667312b370 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -650,7 +650,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                     }
                 }
                 Some(def::DefConst(did)) |
-                Some(def::DefAssociatedConst(did, _)) => {
+                Some(def::DefAssociatedConst(did)) => {
                     if let Some(expr) = const_eval::lookup_const_by_id(v.tcx, did,
                                                                        Some(e.id)) {
                         let inner = v.global_expr(Mode::Const, expr);
@@ -696,10 +696,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                     v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                     true
                 }
-                Some(def::DefMethod(did, def::FromImpl(_))) |
                 Some(def::DefFn(did, _)) => {
                     v.handle_const_fn_call(e, did, node_ty)
                 }
+                Some(def::DefMethod(did)) => {
+                    match v.tcx.impl_or_trait_item(did).container() {
+                        ty::ImplContainer(_) => {
+                            v.handle_const_fn_call(e, did, node_ty)
+                        }
+                        ty::TraitContainer(_) => false
+                    }
+                }
                 _ => false
             };
             if !is_const {
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 7c02045d083..f17cb673a5f 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -35,7 +35,6 @@ use syntax::ast_util;
 use syntax::codemap::{Span, Spanned, DUMMY_SP};
 use syntax::fold::{Folder, noop_fold_pat};
 use syntax::print::pprust::pat_to_string;
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::visit::{self, Visitor, FnKind};
 use util::nodemap::FnvHashMap;
@@ -239,17 +238,17 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
                     let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
                     if let Some(DefLocal(_)) = def {
                         if cx.tcx.enum_variants(def_id).iter().any(|variant|
-                            token::get_name(variant.name) == token::get_name(ident.node.name)
+                            variant.name == ident.node.name
                                 && variant.args.is_empty()
                         ) {
                             span_warn!(cx.tcx.sess, p.span, E0170,
                                 "pattern binding `{}` is named the same as one \
                                  of the variants of the type `{}`",
-                                &token::get_ident(ident.node), pat_ty);
+                                ident.node, pat_ty);
                             fileline_help!(cx.tcx.sess, p.span,
                                 "if you meant to match on a variant, \
                                  consider making the path in the pattern qualified: `{}::{}`",
-                                pat_ty, &token::get_ident(ident.node));
+                                pat_ty, ident.node);
                         }
                     }
                 }
@@ -443,7 +442,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
             ast::PatIdent(..) | ast::PatEnum(..) | ast::PatQPath(..) => {
                 let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
                 match def {
-                    Some(DefAssociatedConst(did, _)) |
+                    Some(DefAssociatedConst(did)) |
                     Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did, Some(pat.id)) {
                         Some(const_expr) => {
                             const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs
index 55a9a919300..77bb53a77bc 100644
--- a/src/librustc/middle/check_static_recursion.rs
+++ b/src/librustc/middle/check_static_recursion.rs
@@ -238,7 +238,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
             ast::ExprPath(..) => {
                 match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
                     Some(DefStatic(def_id, _)) |
-                    Some(DefAssociatedConst(def_id, _)) |
+                    Some(DefAssociatedConst(def_id)) |
                     Some(DefConst(def_id))
                            if ast_util::is_local(def_id) => {
                         match self.ast_map.get(def_id.node) {
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index a349dab0f72..fd1c8d4892a 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -41,7 +41,7 @@ fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
     let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
     match opt_def {
         Some(def::DefConst(def_id)) |
-        Some(def::DefAssociatedConst(def_id, _)) => {
+        Some(def::DefAssociatedConst(def_id)) => {
             lookup_const_by_id(tcx, def_id, Some(e.id))
         }
         Some(def::DefVariant(enum_def, variant_def, _)) => {
@@ -929,10 +929,10 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                       (lookup_const_by_id(tcx, def_id, Some(e.id)), None)
                   }
               }
-              Some(def::DefAssociatedConst(def_id, provenance)) => {
+              Some(def::DefAssociatedConst(def_id)) => {
                   if ast_util::is_local(def_id) {
-                      match provenance {
-                          def::FromTrait(trait_id) => match tcx.map.find(def_id.node) {
+                      match tcx.impl_or_trait_item(def_id).container() {
+                          ty::TraitContainer(trait_id) => match tcx.map.find(def_id.node) {
                               Some(ast_map::NodeTraitItem(ti)) => match ti.node {
                                   ast::ConstTraitItem(ref ty, _) => {
                                       if let ExprTypeChecked = ty_hint {
@@ -950,7 +950,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                               },
                               _ => (None, None)
                           },
-                          def::FromImpl(_) => match tcx.map.find(def_id.node) {
+                          ty::ImplContainer(_) => match tcx.map.find(def_id.node) {
                               Some(ast_map::NodeImplItem(ii)) => match ii.node {
                                   ast::ConstImplItem(ref ty, ref expr) => {
                                       (Some(&**expr), Some(&**ty))
@@ -1036,8 +1036,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             if let Struct(struct_id) = c {
                 if let ast::ExprStruct(_, ref fields, _) = tcx.map.expect_expr(struct_id).node {
                     // Check that the given field exists and evaluate it
-                    if let Some(f) = fields.iter().find(|f| f.ident.node.as_str()
-                                                         == field_name.node.as_str()) {
+                    // if the idents are compared run-pass/issue-19244 fails
+                    if let Some(f) = fields.iter().find(|f| f.ident.node.name
+                                                         == field_name.node.name) {
                         return eval_const_expr_partial(tcx, &*f.expr, base_hint)
                     } else {
                         signal!(e, MissingStructField);
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index bce246fa4af..36c6630c822 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 pub use self::Def::*;
-pub use self::MethodProvenance::*;
 
 use middle::privacy::LastPrivate;
 use middle::subst::ParamSpace;
@@ -28,7 +27,7 @@ pub enum Def {
     DefForeignMod(ast::DefId),
     DefStatic(ast::DefId, bool /* is_mutbl */),
     DefConst(ast::DefId),
-    DefAssociatedConst(ast::DefId /* const */, MethodProvenance),
+    DefAssociatedConst(ast::DefId),
     DefLocal(ast::NodeId),
     DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
     DefTy(ast::DefId, bool /* is_enum */),
@@ -51,7 +50,7 @@ pub enum Def {
     DefStruct(ast::DefId),
     DefRegion(ast::NodeId),
     DefLabel(ast::NodeId),
-    DefMethod(ast::DefId /* method */, MethodProvenance),
+    DefMethod(ast::DefId),
 }
 
 /// The result of resolving a path.
@@ -112,23 +111,6 @@ pub struct Export {
     pub def_id: ast::DefId, // The definition of the target.
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum MethodProvenance {
-    FromTrait(ast::DefId),
-    FromImpl(ast::DefId),
-}
-
-impl MethodProvenance {
-    pub fn map<F>(self, f: F) -> MethodProvenance where
-        F: FnOnce(ast::DefId) -> ast::DefId,
-    {
-        match self {
-            FromTrait(did) => FromTrait(f(did)),
-            FromImpl(did) => FromImpl(f(did))
-        }
-    }
-}
-
 impl Def {
     pub fn local_node_id(&self) -> ast::NodeId {
         let def_id = self.def_id();
@@ -141,7 +123,7 @@ impl Def {
             DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
             DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
             DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
-            DefMethod(id, _) | DefConst(id) | DefAssociatedConst(id, _) |
+            DefMethod(id) | DefConst(id) | DefAssociatedConst(id) |
             DefSelfTy(Some(id), None)=> {
                 id
             }
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index fbf19a10d93..663746ac2dd 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -194,9 +194,7 @@ impl<'tcx> ty::ctxt<'tcx> {
 
             ty::ReEmpty => ("the empty lifetime".to_owned(), None),
 
-            ty::ReEarlyBound(ref data) => {
-                (format!("{}", token::get_name(data.name)), None)
-            }
+            ty::ReEarlyBound(ref data) => (data.name.to_string(), None),
 
             // I believe these cases should not occur (except when debugging,
             // perhaps)
@@ -1056,7 +1054,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
             // choice of lifetime name deterministic and thus easier to test.
             let mut names = Vec::new();
             for rn in region_names {
-                let lt_name = token::get_name(*rn).to_string();
+                let lt_name = rn.to_string();
                 names.push(lt_name);
             }
             names.sort();
@@ -1544,15 +1542,15 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
             }
             infer::LateBoundRegion(_, br, infer::AssocTypeProjection(type_name)) => {
                 format!(" for lifetime parameter {}in trait containing associated type `{}`",
-                        br_string(br), token::get_name(type_name))
+                        br_string(br), type_name)
             }
             infer::EarlyBoundRegion(_, name) => {
                 format!(" for lifetime parameter `{}`",
-                        &token::get_name(name))
+                        name)
             }
             infer::BoundRegionInCoherence(name) => {
                 format!(" for lifetime parameter `{}` in coherence check",
-                        &token::get_name(name))
+                        name)
             }
             infer::UpvarRegion(ref upvar_id, _) => {
                 format!(" for capture of `{}` by closure",
@@ -1838,7 +1836,7 @@ impl LifeGiver {
     fn with_taken(taken: &[ast::LifetimeDef]) -> LifeGiver {
         let mut taken_ = HashSet::new();
         for lt in taken {
-            let lt_name = token::get_name(lt.lifetime.name).to_string();
+            let lt_name = lt.lifetime.name.to_string();
             taken_.insert(lt_name);
         }
         LifeGiver {
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index a10e0b8dfc2..93899a5cf80 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -21,7 +21,6 @@ use syntax::abi::RustIntrinsic;
 use syntax::ast::DefId;
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::parse::token;
 use syntax::visit::Visitor;
 use syntax::visit;
 
@@ -61,16 +60,14 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
         if def_id.krate == ast::LOCAL_CRATE {
             match self.tcx.map.get(def_id.node) {
                 NodeForeignItem(ref item) if intrinsic => {
-                    token::get_ident(item.ident) ==
-                        token::intern_and_get_ident("transmute")
+                    item.ident.name == "transmute"
                 }
                 _ => false,
             }
         } else {
             match csearch::get_item_path(self.tcx, def_id).last() {
                 Some(ref last) if intrinsic => {
-                    token::get_name(last.name()) ==
-                        token::intern_and_get_ident("transmute")
+                    last.name() == "transmute"
                 }
                 _ => false,
             }
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index f7cd94f30af..da1b9f48eda 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -327,6 +327,7 @@ lets_do_this! {
 
     EhPersonalityLangItem,           "eh_personality",          eh_personality;
     EhPersonalityCatchLangItem,      "eh_personality_catch",    eh_personality_catch;
+    EhUnwindResumeLangItem,          "eh_unwind_resume",        eh_unwind_resume;
     MSVCTryFilterLangItem,           "msvc_try_filter",         msvc_try_filter;
 
     ExchangeHeapLangItem,            "exchange_heap",           exchange_heap;
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 7db740798bd..87b8e72f56f 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -122,7 +122,7 @@ use std::io;
 use std::rc::Rc;
 use syntax::ast::{self, NodeId, Expr};
 use syntax::codemap::{BytePos, original_sp, Span};
-use syntax::parse::token::{self, special_idents};
+use syntax::parse::token::special_idents;
 use syntax::print::pprust::{expr_to_string, block_to_string};
 use syntax::ptr::P;
 use syntax::ast_util;
@@ -332,7 +332,7 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
     fn variable_name(&self, var: Variable) -> String {
         match self.var_kinds[var.get()] {
             Local(LocalInfo { name, .. }) | Arg(_, name) => {
-                token::get_name(name).to_string()
+                name.to_string()
             },
             ImplicitRet => "<implicit-ret>".to_string(),
             CleanExit => "<clean-exit>".to_string()
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 76edc8c9b20..95b8161ac34 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -28,7 +28,6 @@ use std::mem::replace;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
-use syntax::parse::token;
 use syntax::print::pprust::lifetime_to_string;
 use syntax::visit;
 use syntax::visit::Visitor;
@@ -664,7 +663,7 @@ impl<'a> LifetimeContext<'a> {
     fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) {
         span_err!(self.sess, lifetime_ref.span, E0261,
             "use of undeclared lifetime name `{}`",
-                    token::get_name(lifetime_ref.name));
+                    lifetime_ref.name);
     }
 
     fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &Vec<ast::LifetimeDef>) {
@@ -675,8 +674,7 @@ impl<'a> LifetimeContext<'a> {
             for lifetime in lifetimes {
                 if special_idents.iter().any(|&i| i.name == lifetime.lifetime.name) {
                     span_err!(self.sess, lifetime.lifetime.span, E0262,
-                        "illegal lifetime parameter name: `{}`",
-                                token::get_name(lifetime.lifetime.name));
+                        "invalid lifetime parameter name: `{}`", lifetime.lifetime.name);
                 }
             }
 
@@ -688,7 +686,7 @@ impl<'a> LifetimeContext<'a> {
                     span_err!(self.sess, lifetime_j.lifetime.span, E0263,
                         "lifetime name `{}` declared twice in \
                                 the same scope",
-                                token::get_name(lifetime_j.lifetime.name));
+                                lifetime_j.lifetime.name);
                 }
             }
 
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 6d3bc7fb68c..7dcf63fcafb 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -339,7 +339,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
         // When compiling with --test we don't enforce stability on the
         // compiler-generated test module, demarcated with `DUMMY_SP` plus the
         // name `__test`
-        if item.span == DUMMY_SP && item.ident.as_str() == "__test" { return }
+        if item.span == DUMMY_SP && item.ident.name == "__test" { return }
 
         check_item(self.tcx, item, true,
                    &mut |id, sp, stab| self.check(id, sp, stab));
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index ad4d015979a..88fc6181f92 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -44,7 +44,7 @@ use metadata::csearch;
 use middle;
 use middle::cast;
 use middle::check_const;
-use middle::const_eval::{self, ConstVal};
+use middle::const_eval::{self, ConstVal, ErrKind};
 use middle::const_eval::EvalHint::UncheckedExprHint;
 use middle::def::{self, DefMap, ExportMap};
 use middle::dependency_format;
@@ -5331,19 +5331,13 @@ impl<'tcx> ctxt<'tcx> {
         match self.map.find(id) {
             Some(ast_map::NodeLocal(pat)) => {
                 match pat.node {
-                    ast::PatIdent(_, ref path1, _) => {
-                        token::get_ident(path1.node)
-                    }
+                    ast::PatIdent(_, ref path1, _) => path1.node.name.as_str(),
                     _ => {
-                        self.sess.bug(&format!("Variable id {} maps to {:?}, not local",
-                                               id, pat));
-                    }
+                        self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, pat));
+                    },
                 }
-            }
-            r => {
-                self.sess.bug(&format!("Variable id {} maps to {:?}, not local",
-                                       id, r));
-            }
+            },
+            r => self.sess.bug(&format!("Variable id {} maps to {:?}, not local", id, r)),
         }
     }
 
@@ -5435,9 +5429,9 @@ impl<'tcx> ctxt<'tcx> {
         for f in fields { if f.name == name { return i; } i += 1; }
         self.sess.bug(&format!(
             "no field named `{}` found in the list of fields `{:?}`",
-            token::get_name(name),
+            name,
             fields.iter()
-                  .map(|f| token::get_name(f.name).to_string())
+                  .map(|f| f.name.to_string())
                   .collect::<Vec<String>>()));
     }
 
@@ -5854,13 +5848,13 @@ impl<'tcx> ctxt<'tcx> {
                                       "expected {} integer constant",
                                       sign_desc);
                             current_disr_val = attempt_fresh_value();
-                        }
+                        },
                         Err(ref err) => {
                             span_err!(self.sess, err.span, E0080,
                                       "constant evaluation error: {}",
                                       err.description());
                             current_disr_val = attempt_fresh_value();
-                        }
+                        },
                     }
                 },
                 None => {
@@ -5869,14 +5863,14 @@ impl<'tcx> ctxt<'tcx> {
                             if let Some(v) = repr_type.disr_incr(prev_disr_val) {
                                 v
                             } else {
-                                self.report_discrim_overflow(v.span, v.node.name.as_str(),
+                                self.report_discrim_overflow(v.span, &v.node.name.name.as_str(),
                                                              repr_type, prev_disr_val);
                                 attempt_fresh_value()
                             }
                         }
-                        None => ty::INITIAL_DISCRIMINANT_VALUE
+                        None => ty::INITIAL_DISCRIMINANT_VALUE,
                     }
-                }
+                },
             }
 
             let variant_info = Rc::new(VariantInfo::from_ast_variant(self, &**v, current_disr_val));
@@ -6113,20 +6107,20 @@ impl<'tcx> ctxt<'tcx> {
                     found);
             }
             Err(err) => {
-                let err_description = err.description();
-                let found = match count_expr.node {
+                let err_msg = match count_expr.node {
                     ast::ExprPath(None, ast::Path {
                         global: false,
                         ref segments,
                         ..
                     }) if segments.len() == 1 =>
-                        format!("{}", "found variable"),
-                    _ =>
-                        format!("but {}", err_description),
+                        format!("found variable"),
+                    _ => match err.kind {
+                        ErrKind::MiscCatchAll => format!("but found {}", err.description()),
+                        _ => format!("but {}", err.description())
+                    }
                 };
                 span_err!(self.sess, count_expr.span, E0307,
-                    "expected constant integer for repeat count, {}",
-                    found);
+                    "expected constant integer for repeat count, {}", err_msg);
             }
         }
         0
@@ -6511,7 +6505,7 @@ impl<'tcx> ctxt<'tcx> {
                         byte!(20);
                         hash!(p.space);
                         hash!(p.idx);
-                        hash!(token::get_name(p.name));
+                        hash!(p.name.as_str());
                     }
                     TyInfer(_) => unreachable!(),
                     TyError => byte!(21),
@@ -6522,7 +6516,7 @@ impl<'tcx> ctxt<'tcx> {
                     TyProjection(ref data) => {
                         byte!(23);
                         did(state, data.trait_ref.def_id);
-                        hash!(token::get_name(data.item_name));
+                        hash!(data.item_name.as_str());
                     }
                 }
                 true
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 72fda9a7ae0..934f7c0688c 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -45,6 +45,10 @@ pub fn check_crate(krate: &ast::Crate,
     if items.eh_personality().is_none() {
         items.missing.push(lang_items::EhPersonalityLangItem);
     }
+    if sess.target.target.options.custom_unwind_resume &
+       items.eh_unwind_resume().is_none() {
+        items.missing.push(lang_items::EhUnwindResumeLangItem);
+    }
 
     {
         let mut cx = Context { sess: sess, items: items };
@@ -122,4 +126,5 @@ weak_lang_items! {
     panic_fmt,          PanicFmtLangItem,           rust_begin_unwind;
     stack_exhausted,    StackExhaustedLangItem,     rust_stack_exhausted;
     eh_personality,     EhPersonalityLangItem,      rust_eh_personality;
+    eh_unwind_resume,   EhUnwindResumeLangItem,     rust_eh_unwind_resume;
 }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index fba8fad203b..f74bb9ee89a 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -84,6 +84,7 @@ pub struct Options {
     pub debug_assertions: bool,
     pub debuginfo: DebugInfoLevel,
     pub lint_opts: Vec<(String, lint::Level)>,
+    pub lint_cap: Option<lint::Level>,
     pub describe_lints: bool,
     pub output_types: Vec<OutputType>,
     // This was mutable for rustpkg, which updates search paths based on the
@@ -203,6 +204,7 @@ pub fn basic_options() -> Options {
         optimize: No,
         debuginfo: NoDebugInfo,
         lint_opts: Vec::new(),
+        lint_cap: None,
         describe_lints: false,
         output_types: Vec::new(),
         search_paths: SearchPaths::new(),
@@ -794,6 +796,9 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
         opt::multi("A", "allow", "Set lint allowed", "OPT"),
         opt::multi("D", "deny", "Set lint denied", "OPT"),
         opt::multi("F", "forbid", "Set lint forbidden", "OPT"),
+        opt::multi("", "cap-lints", "Set the most restrictive lint level. \
+                                     More restrictive lints are capped at this \
+                                     level", "LEVEL"),
         opt::multi("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
         opt::flag("V", "version", "Print version info and exit"),
         opt::flag("v", "verbose", "Use verbose output"),
@@ -823,8 +828,8 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
                    `typed` (crates expanded, with type annotations), or
                    `expanded,identified` (fully parenthesized, AST nodes with IDs).",
                  "TYPE"),
-        opt::flagopt_u("", "xpretty",
-                     "Pretty-print the input instead of compiling, unstable variants;
+        opt::flagopt_u("", "unpretty",
+                     "Present the input source, unstable (and less-pretty) variants;
                       valid types are any of the types for `--pretty`, as well as:
                       `flowgraph=<nodeid>` (graphviz formatted flowgraph for node), or
                       `everybody_loops` (all function bodies replaced with `loop {}`).",
@@ -862,6 +867,12 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         }
     }
 
+    let lint_cap = matches.opt_str("cap-lints").map(|cap| {
+        lint::Level::from_str(&cap).unwrap_or_else(|| {
+            early_error(&format!("unknown lint level: `{}`", cap))
+        })
+    });
+
     let debugging_opts = build_debugging_options(matches);
 
     let parse_only = debugging_opts.parse_only;
@@ -1025,6 +1036,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         optimize: opt_level,
         debuginfo: debuginfo,
         lint_opts: lint_opts,
+        lint_cap: lint_cap,
         describe_lints: describe_lints,
         output_types: output_types,
         search_paths: search_paths,
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index f9416d53a8f..db0a291efbd 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -265,20 +265,20 @@ mod svh_visitor {
             ExprCast(..)             => SawExprCast,
             ExprIf(..)               => SawExprIf,
             ExprWhile(..)            => SawExprWhile,
-            ExprLoop(_, id)          => SawExprLoop(id.map(content)),
+            ExprLoop(_, id)          => SawExprLoop(id.map(|id| id.name.as_str())),
             ExprMatch(..)            => SawExprMatch,
             ExprClosure(..)          => SawExprClosure,
             ExprBlock(..)            => SawExprBlock,
             ExprAssign(..)           => SawExprAssign,
             ExprAssignOp(op, _, _)   => SawExprAssignOp(op.node),
-            ExprField(_, id)         => SawExprField(content(id.node)),
+            ExprField(_, id)         => SawExprField(id.node.name.as_str()),
             ExprTupField(_, id)      => SawExprTupField(id.node),
             ExprIndex(..)            => SawExprIndex,
             ExprRange(..)            => SawExprRange,
             ExprPath(ref qself, _)   => SawExprPath(qself.as_ref().map(|q| q.position)),
             ExprAddrOf(m, _)         => SawExprAddrOf(m),
-            ExprBreak(id)            => SawExprBreak(id.map(content)),
-            ExprAgain(id)            => SawExprAgain(id.map(content)),
+            ExprBreak(id)            => SawExprBreak(id.map(|id| id.name.as_str())),
+            ExprAgain(id)            => SawExprAgain(id.map(|id| id.name.as_str())),
             ExprRet(..)              => SawExprRet,
             ExprInlineAsm(ref asm)   => SawExprInlineAsm(asm),
             ExprStruct(..)           => SawExprStruct,
@@ -310,16 +310,6 @@ mod svh_visitor {
         }
     }
 
-    // Ad-hoc overloading between Ident and Name to their intern table lookups.
-    trait InternKey { fn get_content(self) -> token::InternedString; }
-    impl InternKey for Ident {
-        fn get_content(self) -> token::InternedString { token::get_ident(self) }
-    }
-    impl InternKey for Name {
-        fn get_content(self) -> token::InternedString { token::get_name(self) }
-    }
-    fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
-
     impl<'a, 'v> Visitor<'v> for StrictVersionHashVisitor<'a> {
 
         fn visit_mac(&mut self, mac: &Mac) {
@@ -355,7 +345,7 @@ mod svh_visitor {
                     &MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
                         let s = &path.segments;
                         assert_eq!(s.len(), 1);
-                        content(s[0].identifier)
+                        s[0].identifier.name.as_str()
                     }
                 }
             }
@@ -363,7 +353,7 @@ mod svh_visitor {
 
         fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
                             g: &Generics, _: NodeId) {
-            SawStructDef(content(ident)).hash(self.st);
+            SawStructDef(ident.name.as_str()).hash(self.st);
             visit::walk_generics(self, g);
             visit::walk_struct_def(self, s)
         }
@@ -401,15 +391,15 @@ mod svh_visitor {
         // pattern, please move that method up above this comment.)
 
         fn visit_ident(&mut self, _: Span, ident: Ident) {
-            SawIdent(content(ident)).hash(self.st);
+            SawIdent(ident.name.as_str()).hash(self.st);
         }
 
         fn visit_lifetime_ref(&mut self, l: &Lifetime) {
-            SawLifetimeRef(content(l.name)).hash(self.st);
+            SawLifetimeRef(l.name.as_str()).hash(self.st);
         }
 
         fn visit_lifetime_def(&mut self, l: &LifetimeDef) {
-            SawLifetimeDef(content(l.lifetime.name)).hash(self.st);
+            SawLifetimeDef(l.lifetime.name.as_str()).hash(self.st);
         }
 
         // We do recursively walk the bodies of functions/methods
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 39e42913ff6..ce05a8878ff 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -171,6 +171,11 @@ pub struct TargetOptions {
     /// currently only "gnu" is used to fall into LLVM. Unknown strings cause
     /// the system linker to be used.
     pub archive_format: String,
+    /// Whether the target uses a custom unwind resumption routine.
+    /// By default LLVM lowers `resume` instructions into calls to `_Unwind_Resume`
+    /// defined in libgcc.  If this option is enabled, the target must provide
+    /// `eh_unwind_resume` lang item.
+    pub custom_unwind_resume: bool,
 }
 
 impl Default for TargetOptions {
@@ -209,6 +214,7 @@ impl Default for TargetOptions {
             pre_link_objects: Vec::new(),
             post_link_objects: Vec::new(),
             archive_format: String::new(),
+            custom_unwind_resume: false,
         }
     }
 }
diff --git a/src/librustc_back/target/x86_64_pc_windows_gnu.rs b/src/librustc_back/target/x86_64_pc_windows_gnu.rs
index e4d7b4bc9b0..aef1d7471b8 100644
--- a/src/librustc_back/target/x86_64_pc_windows_gnu.rs
+++ b/src/librustc_back/target/x86_64_pc_windows_gnu.rs
@@ -16,6 +16,7 @@ pub fn target() -> Target {
     // On Win64 unwinding is handled by the OS, so we can link libgcc statically.
     base.pre_link_args.push("-static-libgcc".to_string());
     base.pre_link_args.push("-m64".to_string());
+    base.custom_unwind_resume = true;
 
     Target {
         llvm_target: "x86_64-pc-windows-gnu".to_string(),
diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs
index b59c24cf12b..c4573bd9060 100644
--- a/src/librustc_bitflags/lib.rs
+++ b/src/librustc_bitflags/lib.rs
@@ -34,8 +34,8 @@
 /// # Examples
 ///
 /// ```{.rust}
-/// # #![feature(rustc_private)]
-/// # #![feature(associated_consts)]
+/// #![feature(rustc_private)]
+/// #![feature(associated_consts)]
 /// #[macro_use] extern crate rustc_bitflags;
 ///
 /// bitflags! {
@@ -62,7 +62,7 @@
 /// The generated `struct`s can also be extended with type and trait implementations:
 ///
 /// ```{.rust}
-/// # #![feature(rustc_private)]
+/// #![feature(rustc_private)]
 /// #[macro_use] extern crate rustc_bitflags;
 ///
 /// use std::fmt;
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 78e4945d4b5..e050276fc76 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -39,7 +39,6 @@ use std::rc::Rc;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
-use syntax::parse::token;
 use syntax::visit;
 use syntax::visit::{Visitor, FnKind};
 use syntax::ast::{FnDecl, Block, NodeId};
@@ -1068,7 +1067,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 match fname {
                     mc::NamedField(fname) => {
                         out.push('.');
-                        out.push_str(&token::get_name(fname));
+                        out.push_str(&fname.as_str());
                     }
                     mc::PositionalField(idx) => {
                         out.push('.');
diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs
index 4f90a287cb9..24bbd4fcb7e 100644
--- a/src/librustc_borrowck/diagnostics.rs
+++ b/src/librustc_borrowck/diagnostics.rs
@@ -73,6 +73,28 @@ fn main() {
 
 To fix this, ensure that any declared variables are initialized before being
 used.
+"##,
+
+E0384: r##"
+This error occurs when an attempt is made to reassign an immutable variable.
+For example:
+
+```
+fn main(){
+    let x = 3;
+    x = 5; // error, reassignment of immutable variable
+}
+```
+
+By default, variables in Rust are immutable. To fix this error, add the keyword
+`mut` after the keyword `let` when declaring the variable. For example:
+
+```
+fn main(){
+    let mut x = 3;
+    x = 5;
+}
+```
 "##
 
 }
@@ -80,7 +102,6 @@ used.
 register_diagnostics! {
     E0382, // use of partially/collaterally moved value
     E0383, // partial reinitialization of uninitialized structure
-    E0384, // reassignment of immutable variable
     E0385, // {} in an aliasable location
     E0386, // {} in an immutable container
     E0387, // {} in a captured outer variable in an `Fn` closure
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 873950b0be8..13d7c7b41a0 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -339,7 +339,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
             None
         };
         if pretty.is_none() && sess.unstable_options() {
-            matches.opt_str("xpretty").map(|a| {
+            matches.opt_str("unpretty").map(|a| {
                 // extended with unstable pretty-print variants
                 pretty::parse_pretty(sess, &a, true)
             })
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 0e735cbb7ff..818ce005d4c 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -60,7 +60,7 @@ pub enum PpSourceMode {
 pub enum PpFlowGraphMode {
     Default,
     /// Drops the labels from the edges in the flowgraph output. This
-    /// is mostly for use in the --xpretty flowgraph run-make tests,
+    /// is mostly for use in the --unpretty flowgraph run-make tests,
     /// since the labels are largely uninteresting in those cases and
     /// have become a pain to maintain.
     UnlabelledEdges,
@@ -90,7 +90,7 @@ pub fn parse_pretty(sess: &Session,
         _ => {
             if extended {
                 sess.fatal(&format!(
-                    "argument to `xpretty` must be one of `normal`, \
+                    "argument to `unpretty` must be one of `normal`, \
                      `expanded`, `flowgraph[,unlabelled]=<nodeid>`, `typed`, `identified`, \
                      `expanded,identified`, or `everybody_loops`; got {}", name));
             } else {
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 751224e7286..ffd09326abc 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -33,7 +33,6 @@
 
 use metadata::{csearch, decoder};
 use middle::{cfg, def, infer, pat_util, stability, traits};
-use middle::def::*;
 use middle::subst::Substs;
 use middle::ty::{self, Ty};
 use middle::const_eval::{eval_const_expr_partial, ConstVal};
@@ -53,7 +52,6 @@ use syntax::ast_util::{self, is_shift_binop, local_def};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::codemap::{self, Span};
 use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
-use syntax::parse::token;
 use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
 use syntax::ptr::P;
 use syntax::visit::{self, Visitor};
@@ -1043,7 +1041,7 @@ pub struct NonCamelCaseTypes;
 impl NonCamelCaseTypes {
     fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
         fn is_camel_case(ident: ast::Ident) -> bool {
-            let ident = token::get_ident(ident);
+            let ident = ident.name.as_str();
             if ident.is_empty() {
                 return true;
             }
@@ -1064,7 +1062,7 @@ impl NonCamelCaseTypes {
             )).collect::<Vec<_>>().concat()
         }
 
-        let s = token::get_ident(ident);
+        let s = ident.name.as_str();
 
         if !is_camel_case(ident) {
             let c = to_camel_case(&s);
@@ -1245,15 +1243,15 @@ impl LintPass for NonSnakeCase {
         match fk {
             visit::FkMethod(ident, _, _) => match method_context(cx, id, span) {
                 MethodContext::PlainImpl => {
-                    self.check_snake_case(cx, "method", &token::get_ident(ident), Some(span))
+                    self.check_snake_case(cx, "method", &ident.name.as_str(), Some(span))
                 },
                 MethodContext::TraitDefaultImpl => {
-                    self.check_snake_case(cx, "trait method", &token::get_ident(ident), Some(span))
+                    self.check_snake_case(cx, "trait method", &ident.name.as_str(), Some(span))
                 },
                 _ => (),
             },
             visit::FkItemFn(ident, _, _, _, _, _) => {
-                self.check_snake_case(cx, "function", &token::get_ident(ident), Some(span))
+                self.check_snake_case(cx, "function", &ident.name.as_str(), Some(span))
             },
             _ => (),
         }
@@ -1261,19 +1259,19 @@ impl LintPass for NonSnakeCase {
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
         if let ast::ItemMod(_) = it.node {
-            self.check_snake_case(cx, "module", &token::get_ident(it.ident), Some(it.span));
+            self.check_snake_case(cx, "module", &it.ident.name.as_str(), Some(it.span));
         }
     }
 
     fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
         if let ast::MethodTraitItem(_, None) = trait_item.node {
-            self.check_snake_case(cx, "trait method", &token::get_ident(trait_item.ident),
+            self.check_snake_case(cx, "trait method", &trait_item.ident.name.as_str(),
                                   Some(trait_item.span));
         }
     }
 
     fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
-        self.check_snake_case(cx, "lifetime", &token::get_ident(t.lifetime.name.ident()),
+        self.check_snake_case(cx, "lifetime", &t.lifetime.name.as_str(),
                               Some(t.lifetime.span));
     }
 
@@ -1281,7 +1279,7 @@ impl LintPass for NonSnakeCase {
         if let &ast::PatIdent(_, ref path1, _) = &p.node {
             let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
             if let Some(def::DefLocal(_)) = def {
-                self.check_snake_case(cx, "variable", &token::get_ident(path1.node), Some(p.span));
+                self.check_snake_case(cx, "variable", &path1.node.name.as_str(), Some(p.span));
             }
         }
     }
@@ -1290,7 +1288,7 @@ impl LintPass for NonSnakeCase {
                         _: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
         for sf in &s.fields {
             if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node {
-                self.check_snake_case(cx, "structure field", &token::get_ident(ident),
+                self.check_snake_case(cx, "structure field", &ident.name.as_str(),
                                       Some(sf.span));
             }
         }
@@ -1308,7 +1306,7 @@ pub struct NonUpperCaseGlobals;
 
 impl NonUpperCaseGlobals {
     fn check_upper_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
-        let s = token::get_ident(ident);
+        let s = ident.name.as_str();
 
         if s.chars().any(|c| c.is_lowercase()) {
             let uc = NonSnakeCase::to_snake_case(&s).to_uppercase();
@@ -1489,7 +1487,7 @@ impl LintPass for UnusedImportBraces {
                 if items.len() == 1 {
                     if let ast::PathListIdent {ref name, ..} = items[0].node {
                         let m = format!("braces around {} is unnecessary",
-                                        &token::get_ident(*name));
+                                        name);
                         cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
                                      &m[..]);
                     }
@@ -1525,10 +1523,12 @@ impl LintPass for NonShorthandFieldPatterns {
             });
             for fieldpat in field_pats {
                 if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
-                    if ident.node.as_str() == fieldpat.node.ident.as_str() {
+                    if ident.node.name == fieldpat.node.ident.name {
+                        // FIXME: should this comparison really be done on the name?
+                        // doing it on the ident will fail during compilation of libcore
                         cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
                                      &format!("the `{}:` in this pattern is redundant and can \
-                                              be removed", ident.node.as_str()))
+                                              be removed", ident.node))
                     }
                 }
             }
@@ -1641,7 +1641,7 @@ impl UnusedMut {
             pat_util::pat_bindings(&cx.tcx.def_map, &**p, |mode, id, _, path1| {
                 let ident = path1.node;
                 if let ast::BindByValue(ast::MutMutable) = mode {
-                    if !token::get_ident(ident).starts_with("_") {
+                    if !ident.name.as_str().starts_with("_") {
                         match mutables.entry(ident.name.usize()) {
                             Vacant(entry) => { entry.insert(vec![id]); },
                             Occupied(mut entry) => { entry.get_mut().push(id); },
@@ -2250,34 +2250,73 @@ impl LintPass for UnconditionalRecursion {
             }
         }
 
-        // Check if the method call `id` refers to method `method`.
+        // Check if the expression `id` performs a call to `method`.
         fn expr_refers_to_this_method(tcx: &ty::ctxt,
                                       method: &ty::Method,
                                       id: ast::NodeId) -> bool {
-            let method_call = ty::MethodCall::expr(id);
-            let callee = match tcx.tables.borrow().method_map.get(&method_call) {
-                Some(&m) => m,
-                None => return false
-            };
-            let callee_item = tcx.impl_or_trait_item(callee.def_id);
+            let tables = tcx.tables.borrow();
+
+            // Check for method calls and overloaded operators.
+            if let Some(m) = tables.method_map.get(&ty::MethodCall::expr(id)) {
+                if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) {
+                    return true;
+                }
+            }
+
+            // Check for overloaded autoderef method calls.
+            if let Some(&ty::AdjustDerefRef(ref adj)) = tables.adjustments.get(&id) {
+                for i in 0..adj.autoderefs {
+                    let method_call = ty::MethodCall::autoderef(id, i as u32);
+                    if let Some(m) = tables.method_map.get(&method_call) {
+                        if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) {
+                            return true;
+                        }
+                    }
+                }
+            }
+
+            // Check for calls to methods via explicit paths (e.g. `T::method()`).
+            match tcx.map.get(id) {
+                ast_map::NodeExpr(&ast::Expr { node: ast::ExprCall(ref callee, _), .. }) => {
+                    match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) {
+                        Some(def::DefMethod(def_id)) => {
+                            let no_substs = &ty::ItemSubsts::empty();
+                            let ts = tables.item_substs.get(&callee.id).unwrap_or(no_substs);
+                            method_call_refers_to_method(tcx, method, def_id, &ts.substs, id)
+                        }
+                        _ => false
+                    }
+                }
+                _ => false
+            }
+        }
+
+        // Check if the method call to the method with the ID `callee_id`
+        // and instantiated with `callee_substs` refers to method `method`.
+        fn method_call_refers_to_method<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                              method: &ty::Method,
+                                              callee_id: ast::DefId,
+                                              callee_substs: &Substs<'tcx>,
+                                              expr_id: ast::NodeId) -> bool {
+            let callee_item = tcx.impl_or_trait_item(callee_id);
 
             match callee_item.container() {
                 // This is an inherent method, so the `def_id` refers
                 // directly to the method definition.
                 ty::ImplContainer(_) => {
-                    callee.def_id == method.def_id
+                    callee_id == method.def_id
                 }
 
                 // A trait method, from any number of possible sources.
                 // Attempt to select a concrete impl before checking.
                 ty::TraitContainer(trait_def_id) => {
-                    let trait_substs = callee.substs.clone().method_to_trait();
+                    let trait_substs = callee_substs.clone().method_to_trait();
                     let trait_substs = tcx.mk_substs(trait_substs);
                     let trait_ref = ty::TraitRef::new(trait_def_id, trait_substs);
                     let trait_ref = ty::Binder(trait_ref);
-                    let span = tcx.map.span(id);
+                    let span = tcx.map.span(expr_id);
                     let obligation =
-                        traits::Obligation::new(traits::ObligationCause::misc(span, id),
+                        traits::Obligation::new(traits::ObligationCause::misc(span, expr_id),
                                                 trait_ref.to_poly_trait_predicate());
 
                     let param_env = ty::ParameterEnvironment::for_item(tcx, method.def_id.node);
@@ -2288,12 +2327,12 @@ impl LintPass for UnconditionalRecursion {
                         // If `T` is `Self`, then this call is inside
                         // a default method definition.
                         Ok(Some(traits::VtableParam(_))) => {
-                            let self_ty = callee.substs.self_ty();
+                            let self_ty = callee_substs.self_ty();
                             let on_self = self_ty.map_or(false, |t| t.is_self());
                             // We can only be recurring in a default
                             // method if we're being called literally
                             // on the `Self` type.
-                            on_self && callee.def_id == method.def_id
+                            on_self && callee_id == method.def_id
                         }
 
                         // The `impl` is known, so we check that with a
@@ -2453,7 +2492,7 @@ impl LintPass for MutableTransmutes {
                 ast::ExprPath(..) => (),
                 _ => return None
             }
-            if let DefFn(did, _) = cx.tcx.resolve_expr(expr) {
+            if let def::DefFn(did, _) = cx.tcx.resolve_expr(expr) {
                 if !def_id_is_transmute(cx, did) {
                     return None;
                 }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index d90e5a033a1..2ffb4cbd4bf 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -46,7 +46,6 @@ use rustc::util::nodemap::{NodeMap, NodeSet};
 use syntax::ast;
 use syntax::ast_util::{is_local, local_def};
 use syntax::codemap::Span;
-use syntax::parse::token;
 use syntax::visit::{self, Visitor};
 
 type Context<'a, 'tcx> = (&'a ty::MethodMap<'tcx>, &'a def::ExportMap);
@@ -682,8 +681,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             ast::ItemEnum(..) => "enum",
             _ => return Some((err_span, err_msg, None))
         };
-        let msg = format!("{} `{}` is private", desc,
-                          token::get_ident(item.ident));
+        let msg = format!("{} `{}` is private", desc, item.ident);
         Some((err_span, err_msg, Some((span, msg))))
     }
 
@@ -715,7 +713,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
         };
         let msg = match name {
             NamedField(name) => format!("field `{}` of {} is private",
-                                        token::get_name(name), struct_desc),
+                                        name, struct_desc),
             UnnamedField(idx) => format!("field #{} of {} is private",
                                          idx + 1, struct_desc),
         };
@@ -740,12 +738,11 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             }
         };
 
-        let string = token::get_name(name);
         self.report_error(self.ensure_public(span,
                                              method_id,
                                              None,
                                              &format!("method `{}`",
-                                                     string)));
+                                                     name)));
     }
 
     // Checks that a path is in scope.
@@ -755,12 +752,11 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
         let ck = |tyname: &str| {
             let ck_public = |def: ast::DefId| {
                 debug!("privacy - ck_public {:?}", def);
-                let name = token::get_name(last);
                 let origdid = path_res.def_id();
                 self.ensure_public(span,
                                    def,
                                    Some(origdid),
-                                   &format!("{} `{}`", tyname, name))
+                                   &format!("{} `{}`", tyname, last))
             };
 
             match path_res.last_private {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index aa7f93776da..656d6a36614 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -52,7 +52,7 @@ use syntax::ast::Visibility;
 use syntax::ast;
 use syntax::ast_util::local_def;
 use syntax::attr::AttrMetaMethods;
-use syntax::parse::token::{self, special_idents};
+use syntax::parse::token::special_idents;
 use syntax::codemap::{Span, DUMMY_SP};
 use syntax::visit::{self, Visitor};
 
@@ -222,7 +222,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                             self.session.span_note(sp,
                                  &format!("first definition of {} `{}` here",
                                       namespace_error_to_string(duplicate_type),
-                                      token::get_name(name)));
+                                      name));
                         }
                     }
                 }
@@ -294,7 +294,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
                 // Build up the import directives.
                 let shadowable = item.attrs.iter().any(|attr| {
-                    attr.name() == token::get_name(special_idents::prelude_import.name)
+                    attr.name() == special_idents::prelude_import.name.as_str()
                 });
                 let shadowable = if shadowable {
                     Shadowable::Always
@@ -306,12 +306,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     ViewPathSimple(binding, ref full_path) => {
                         let source_name =
                             full_path.segments.last().unwrap().identifier.name;
-                        if &token::get_name(source_name)[..] == "mod" ||
-                           &token::get_name(source_name)[..] == "self" {
+                        if source_name.as_str() == "mod" || source_name.as_str() == "self" {
                             resolve_error(self,
-                                            view_path.span,
-                                            ResolutionError::SelfImportsOnlyAllowedWithin
-                            );
+                                          view_path.span,
+                                          ResolutionError::SelfImportsOnlyAllowedWithin);
                         }
 
                         let subclass = SingleImport(binding.name,
@@ -547,14 +545,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
                     match trait_item.node {
                         ast::ConstTraitItem(..) => {
-                            let def = DefAssociatedConst(local_def(trait_item.id),
-                                                         FromTrait(local_def(item.id)));
+                            let def = DefAssociatedConst(local_def(trait_item.id));
                             // NB: not DefModifiers::IMPORTABLE
                             name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
                         }
                         ast::MethodTraitItem(..) => {
-                            let def = DefMethod(local_def(trait_item.id),
-                                                FromTrait(local_def(item.id)));
+                            let def = DefMethod(local_def(trait_item.id));
                             // NB: not DefModifiers::IMPORTABLE
                             name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
                         }
@@ -763,7 +759,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
                   debug!("(building reduced graph for external crate) ... \
                           adding trait item '{}'",
-                         token::get_name(trait_item_name));
+                         trait_item_name);
 
                   self.trait_item_map.insert((trait_item_name, def_id),
                                              trait_item_def.def_id());
@@ -849,7 +845,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                         self.handle_external_def(def,
                                                  def_visibility,
                                                  &*child_name_bindings,
-                                                 &token::get_name(name),
+                                                 &name.as_str(),
                                                  name,
                                                  root);
                     }
@@ -883,7 +879,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                     def_id,
                                     |def_like, child_name, visibility| {
             debug!("(populating external module) ... found ident: {}",
-                   token::get_name(child_name));
+                   child_name);
             self.build_reduced_graph_for_external_crate_def(module,
                                                             def_like,
                                                             child_name,
@@ -937,7 +933,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             SingleImport(target, _) => {
                 debug!("(building import directive) building import directive: {}::{}",
                        names_to_string(&module_.imports.borrow().last().unwrap().module_path),
-                       token::get_name(target));
+                       target);
 
                 let mut import_resolutions = module_.import_resolutions.borrow_mut();
                 match import_resolutions.get_mut(&target) {
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 5ddc2547fd9..2696ca378f7 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -106,7 +106,7 @@ mod foo {
 use foo::MyTrait::do_something;
 ```
 
-It's illegal to directly import methods belonging to a trait or concrete type.
+It's invalid to directly import methods belonging to a trait or concrete type.
 "##,
 
 E0255: r##"
@@ -583,9 +583,10 @@ Please verify you didn't misspell the import's name.
 "##,
 
 E0437: r##"
-Trait impls can only implement associated types that are members of the trait in
-question. This error indicates that you attempted to implement an associated
-type whose name does not match the name of any associated type in the trait.
+Trait implementations can only implement associated types that are members of
+the trait in question. This error indicates that you attempted to implement
+an associated type whose name does not match the name of any associated type
+in the trait.
 
 Here is an example that demonstrates the error:
 
@@ -607,10 +608,10 @@ impl Foo for i32 {}
 "##,
 
 E0438: r##"
-Trait impls can only implement associated constants that are members of the
-trait in question. This error indicates that you attempted to implement an
-associated constant whose name does not match the name of any associated
-constant in the trait.
+Trait implementations can only implement associated constants that are
+members of the trait in question. This error indicates that you
+attempted to implement an associated constant whose name does not
+match the name of any associated constant in the trait.
 
 Here is an example that demonstrates the error:
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index a3a0398e5ce..3e22b42836b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -313,8 +313,8 @@ fn resolve_error<'b, 'a:'b, 'tcx:'a>(resolver: &'b Resolver<'a, 'tcx>, span: syn
         },
         ResolutionError::StructVariantUsedAsFunction(path_name) => {
             span_err!(resolver.session, span, E0423,
-                         "`{}` is a struct variant name, but \
-                          this expression \
+                         "`{}` is the name of a struct or struct variant, \
+                          but this expression \
                           uses it like a function name",
                           path_name);
         },
@@ -1275,7 +1275,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                               name_search_type,
                                               false) {
                 Failed(None) => {
-                    let segment_name = token::get_name(name);
+                    let segment_name = name.as_str();
                     let module_name = module_to_string(&*search_module);
                     let mut span = span;
                     let msg = if "???" == &module_name[..] {
@@ -1688,27 +1688,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                  -> ResolveResult<ModulePrefixResult> {
         // Start at the current module if we see `self` or `super`, or at the
         // top of the crate otherwise.
-        let mut containing_module;
-        let mut i;
-        let first_module_path_string = token::get_name(module_path[0]);
-        if "self" == &first_module_path_string[..] {
-            containing_module =
-                self.get_nearest_normal_module_parent_or_self(module_);
-            i = 1;
-        } else if "super" == &first_module_path_string[..] {
-            containing_module =
-                self.get_nearest_normal_module_parent_or_self(module_);
-            i = 0;  // We'll handle `super` below.
-        } else {
-            return Success(NoPrefixFound);
-        }
+        let mut i = match &*module_path[0].as_str() {
+            "self" => 1,
+            "super" => 0,
+            _ => return Success(NoPrefixFound),
+        };
+        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
 
         // Now loop through all the `super`s we find.
-        while i < module_path.len() {
-            let string = token::get_name(module_path[i]);
-            if "super" != &string[..] {
-                break
-            }
+        while i < module_path.len() && "super" == module_path[i].as_str() {
             debug!("(resolving module prefix) resolving `super` at {}",
                    module_to_string(&*containing_module));
             match self.get_nearest_normal_module_parent(containing_module) {
@@ -2666,23 +2654,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let pat_id = pattern.id;
         walk_pat(pattern, |pattern| {
             match pattern.node {
-                PatIdent(binding_mode, ref path1, _) => {
-
-                    // The meaning of pat_ident with no type parameters
+                PatIdent(binding_mode, ref path1, ref at_rhs) => {
+                    // The meaning of PatIdent with no type parameters
                     // depends on whether an enum variant or unit-like struct
                     // with that name is in scope. The probing lookup has to
                     // be careful not to emit spurious errors. Only matching
                     // patterns (match) can match nullary variants or
-                    // unit-like structs. For binding patterns (let), matching
-                    // such a value is simply disallowed (since it's rarely
-                    // what you want).
+                    // unit-like structs. For binding patterns (let
+                    // and the LHS of @-patterns), matching such a value is
+                    // simply disallowed (since it's rarely what you want).
+                    let const_ok = mode == RefutableMode && at_rhs.is_none();
 
                     let ident = path1.node;
                     let renamed = mtwt::resolve(ident);
 
                     match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
-                        FoundStructOrEnumVariant(def, lp)
-                                if mode == RefutableMode => {
+                        FoundStructOrEnumVariant(def, lp) if const_ok => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     struct or enum variant",
                                    renamed);
@@ -2705,7 +2692,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     renamed)
                             );
                         }
-                        FoundConst(def, lp) if mode == RefutableMode => {
+                        FoundConst(def, lp) if const_ok => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     constant",
                                    renamed);
@@ -2761,7 +2748,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     self,
                                     pattern.span,
                                     ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
-                                        &*token::get_ident(ident))
+                                        &ident.name.as_str())
                                 );
                             } else if bindings_list.get(&renamed) ==
                                     Some(&pat_id) {
@@ -2771,7 +2758,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     self,
                                     pattern.span,
                                     ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
-                                        &*token::get_ident(ident))
+                                        &ident.name.as_str())
                                 );
                             }
                             // Else, not bound in the same pattern: do
@@ -2817,9 +2804,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                         self,
                                         path.span,
                                         ResolutionError::NotAnEnumVariantStructOrConst(
-                                            &*token::get_ident(
-                                                path.segments.last().unwrap().identifier)
-                                            )
+                                            &path.segments
+                                                 .last()
+                                                 .unwrap()
+                                                 .identifier
+                                                 .name
+                                                 .as_str())
                                     );
                                 } else {
                                     let const_name = path.segments.last().unwrap()
@@ -2835,7 +2825,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             self,
                             path.span,
                             ResolutionError::UnresolvedEnumVariantStructOrConst(
-                                &*token::get_ident(path.segments.last().unwrap().identifier))
+                                &path.segments.last().unwrap().identifier.name.as_str())
                         );
                     }
                     visit::walk_path(self, path);
@@ -2872,8 +2862,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     self,
                                     path.span,
                                     ResolutionError::NotAnAssociatedConst(
-                                        &*token::get_ident(
-                                            path.segments.last().unwrap().identifier)
+                                        &path.segments.last().unwrap().identifier.name.as_str()
                                     )
                                 );
                             }
@@ -2883,7 +2872,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             self,
                             path.span,
                             ResolutionError::UnresolvedAssociatedConst(
-                                &*token::get_ident(path.segments.last().unwrap().identifier)
+                                &path.segments.last().unwrap().identifier.name.as_str()
                             )
                         );
                     }
@@ -3304,7 +3293,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match search_result {
             Some(DlDef(def)) => {
                 debug!("(resolving path in local ribs) resolved `{}` to local: {:?}",
-                       token::get_ident(ident),
+                       ident,
                        def);
                 Some(def)
             }
@@ -3459,7 +3448,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // Look for a method in the current self type's impl module.
         if let Some(module) = get_module(self, path.span, &name_path) {
             if let Some(binding) = module.children.borrow().get(&name) {
-                if let Some(DefMethod(did, _)) = binding.def_for_namespace(ValueNS) {
+                if let Some(DefMethod(did)) = binding.def_for_namespace(ValueNS) {
                     if is_static_method(self, did) {
                         return StaticMethod(path_names_to_string(&path, 0))
                     }
@@ -3492,7 +3481,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         for rib in self.value_ribs.iter().rev() {
             for (&k, _) in &rib.bindings {
-                maybes.push(token::get_name(k));
+                maybes.push(k.as_str());
                 values.push(usize::MAX);
             }
         }
@@ -3624,8 +3613,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 false // Stop advancing
                             });
 
-                            if method_scope &&
-                               &token::get_name(special_names::self_)[..] == path_name {
+                            if method_scope && special_names::self_ == path_name {
                                 resolve_error(
                                     self,
                                     expr.span,
@@ -3706,7 +3694,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     None => {
                         resolve_error(self,
                                       expr.span,
-                                      ResolutionError::UndeclaredLabel(&*token::get_ident(label)))
+                                      ResolutionError::UndeclaredLabel(&label.name.as_str()))
                     }
                     Some(DlDef(def @ DefLabel(_))) => {
                         // Since this def is a label, it is never read.
@@ -3912,7 +3900,7 @@ fn names_to_string(names: &[Name]) -> String {
         } else {
             result.push_str("::")
         }
-        result.push_str(&token::get_name(*name));
+        result.push_str(&name.as_str());
     };
     result
 }
diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs
index 3a566a9672f..732c627816c 100644
--- a/src/librustc_resolve/record_exports.rs
+++ b/src/librustc_resolve/record_exports.rs
@@ -26,7 +26,6 @@ use module_to_string;
 
 use rustc::middle::def::Export;
 use syntax::ast;
-use syntax::parse::token;
 
 use std::ops::{Deref, DerefMut};
 use std::rc::Rc;
@@ -143,7 +142,7 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
                 match import_resolution.target_for_namespace(ns) {
                     Some(target) => {
                         debug!("(computing exports) maybe export '{}'",
-                               token::get_name(*name));
+                               name);
                         self.add_exports_of_namebindings(exports,
                                                          *name,
                                                          &*target.bindings,
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index ec02963980b..0a88a3c0aef 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -31,7 +31,6 @@ use rustc::middle::privacy::*;
 
 use syntax::ast::{DefId, NodeId, Name};
 use syntax::attr::AttrMetaMethods;
-use syntax::parse::token;
 use syntax::codemap::Span;
 
 use std::mem::replace;
@@ -435,10 +434,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                                                (*child_name_bindings).clone());
                     if directive.is_public && !child_name_bindings.is_public(ValueNS) {
                         let msg = format!("`{}` is private, and cannot be reexported",
-                                          token::get_name(source));
+                                          source);
                         let note_msg =
                             format!("Consider marking `{}` as `pub` in the imported module",
-                                    token::get_name(source));
+                                    source);
                         span_err!(self.resolver.session, directive.span, E0364, "{}", &msg);
                         self.resolver.session.span_note(directive.span, &note_msg);
                         pub_err = true;
@@ -450,9 +449,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                                               (*child_name_bindings).clone());
                     if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
                         let msg = format!("`{}` is private, and cannot be reexported",
-                                          token::get_name(source));
+                                          source);
                         let note_msg = format!("Consider declaring module `{}` as a `pub mod`",
-                                               token::get_name(source));
+                                               source);
                         span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
                         self.resolver.session.span_note(directive.span, &note_msg);
                     }
@@ -1041,9 +1040,7 @@ fn import_path_to_string(names: &[Name],
 
 fn import_directive_subclass_to_string(subclass: ImportDirectiveSubclass) -> String {
     match subclass {
-        SingleImport(_, source) => {
-            token::get_name(source).to_string()
-        }
+        SingleImport(_, source) => source.to_string(),
         GlobImport => "*".to_string()
     }
 }
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index d7849e8f555..5bdc76bd7c2 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -306,7 +306,7 @@ pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI,
 
     // First, connect each component with <len, name> pairs.
     for e in path {
-        push(&mut n, &token::get_name(e.name()))
+        push(&mut n, &e.name().as_str())
     }
 
     match hash {
diff --git a/src/librustc_trans/back/msvc/mod.rs b/src/librustc_trans/back/msvc/mod.rs
index bc0573d8281..87d3fd1c0e8 100644
--- a/src/librustc_trans/back/msvc/mod.rs
+++ b/src/librustc_trans/back/msvc/mod.rs
@@ -206,7 +206,7 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
         return max_key
     }
 
-    fn get_windows_sdk_path() -> Option<(PathBuf, usize)> {
+    fn get_windows_sdk_path() -> Option<(PathBuf, usize, Option<OsString>)> {
         let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows";
         let key = LOCAL_MACHINE.open(key.as_ref());
         let (n, k) = match key.ok().as_ref().and_then(max_version) {
@@ -217,19 +217,20 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
         let major = parts.next().unwrap().parse::<usize>().unwrap();
         let _minor = parts.next().unwrap().parse::<usize>().unwrap();
         k.query_str("InstallationFolder").ok().map(|folder| {
-            (PathBuf::from(folder), major)
+            let ver = k.query_str("ProductVersion");
+            (PathBuf::from(folder), major, ver.ok())
         })
     }
 
     fn get_windows_sdk_lib_path(sess: &Session) -> Option<PathBuf> {
-        let (mut path, major) = match get_windows_sdk_path() {
+        let (mut path, major, ver) = match get_windows_sdk_path() {
             Some(p) => p,
             None => return None,
         };
         path.push("Lib");
         if major <= 7 {
             // In Windows SDK 7.x, x86 libraries are directly in the Lib folder,
-            // x64 libraries are inside, and it's not necessary to link agains
+            // x64 libraries are inside, and it's not necessary to link against
             // the SDK 7.x when targeting ARM or other architectures.
             let x86 = match &sess.target.target.arch[..] {
                 "x86" => true,
@@ -237,8 +238,8 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
                 _ => return None,
             };
             Some(if x86 {path} else {path.join("x64")})
-        } else {
-            // Windows SDK 8.x installes libraries in a folder whose names
+        } else if major <= 8 {
+            // Windows SDK 8.x installs libraries in a folder whose names
             // depend on the version of the OS you're targeting. By default
             // choose the newest, which usually corresponds to the version of
             // the OS you've installed the SDK on.
@@ -251,7 +252,25 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
             }).map(|path| {
                 path.join("um").join(extra)
             })
-        }
+        } else if let Some(mut ver) = ver {
+            // Windows SDK 10 splits the libraries into architectures the same
+            // as Windows SDK 8.x, except for the addition of arm64.
+            // Additionally, the SDK 10 is split by Windows 10 build numbers
+            // rather than the OS version like the SDK 8.x does.
+            let extra = match windows_sdk_v10_subdir(sess) {
+                Some(e) => e,
+                None => return None,
+            };
+            // To get the correct directory we need to get the Windows SDK 10
+            // version, and so far it looks like the "ProductVersion" of the SDK
+            // corresponds to the folder name that the libraries are located in
+            // except that the folder contains an extra ".0". For now just
+            // append a ".0" to look for find the directory we're in. This logic
+            // will likely want to be refactored one day.
+            ver.push(".0");
+            let p = path.join(ver).join("um").join(extra);
+            fs::metadata(&p).ok().map(|_| p)
+        } else { None }
     }
 
     fn windows_sdk_v8_subdir(sess: &Session) -> Option<&'static str> {
@@ -263,6 +282,16 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
         }
     }
 
+    fn windows_sdk_v10_subdir(sess: &Session) -> Option<&'static str> {
+        match &sess.target.target.arch[..] {
+            "x86" => Some("x86"),
+            "x86_64" => Some("x64"),
+            "arm" => Some("arm"),
+            "aarch64" => Some("arm64"), // FIXME - Check if aarch64 is correct
+            _ => return None,
+        }
+    }
+
     fn ucrt_install_dir(vs_install_dir: &Path) -> Option<(PathBuf, String)> {
         let is_vs_14 = vs_install_dir.iter().filter_map(|p| p.to_str()).any(|s| {
             s == "Microsoft Visual Studio 14.0"
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index d1204c7a0a3..1fbec6f66cf 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -40,7 +40,7 @@ use std::path::Path;
 
 use syntax::ast::{self, NodeId, DefId};
 use syntax::codemap::*;
-use syntax::parse::token::{self, get_ident, keywords};
+use syntax::parse::token::{self, keywords};
 use syntax::owned_slice::OwnedSlice;
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{path_to_string, ty_to_string};
@@ -302,7 +302,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
             return;
         }
 
-        debug!("process_method: {}:{}", id, token::get_name(name));
+        debug!("process_method: {}:{}", id, name);
 
         let method_data = self.save_ctxt.get_method_data(id, name, span);
 
@@ -459,7 +459,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         self.fmt.static_str(span,
                             sub_span,
                             id,
-                            &get_ident((*ident).clone()),
+                            &ident.name.as_str(),
                             &qualname,
                             &self.span.snippet(expr.span),
                             &ty_to_string(&*typ),
@@ -513,7 +513,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                           &enum_data.value);
 
         for variant in &enum_definition.variants {
-            let name = &get_ident(variant.node.name);
+            let name = &variant.node.name.name.as_str();
             let mut qualname = enum_data.qualname.clone();
             qualname.push_str("::");
             qualname.push_str(name);
@@ -719,7 +719,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         let def_map = self.tcx.def_map.borrow();
         let def = def_map.get(&id).unwrap().full_def();
         match def {
-            def::DefMethod(did, _) => {
+            def::DefMethod(did) => {
                 let ti = self.tcx.impl_or_trait_item(did);
                 if let ty::MethodTraitItem(m) = ti {
                     if m.explicit_self == ty::StaticExplicitSelfCategory {
@@ -886,7 +886,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                                sub_span,
                                                item.id,
                                                mod_id,
-                                               &get_ident(ident),
+                                               &ident.name.as_str(),
                                                self.cur_scope);
                         self.write_sub_paths_truncated(path, true);
                     }
@@ -900,7 +900,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                 if !name_string.is_empty() {
                                     name_string.push_str(", ");
                                 }
-                                name_string.push_str(n.as_str());
+                                name_string.push_str(&n.as_str());
                             }
                         }
 
@@ -940,11 +940,9 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                 }
             }
             ast::ItemExternCrate(ref s) => {
-                let name = get_ident(item.ident);
-                let name = &name;
                 let location = match *s {
                     Some(s) => s.to_string(),
-                    None => name.to_string(),
+                    None => item.ident.to_string(),
                 };
                 let alias_span = self.span.span_for_last_ident(item.span);
                 let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
@@ -955,7 +953,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                                           alias_span,
                                           item.id,
                                           cnum,
-                                          name,
+                                          &item.ident.name.as_str(),
                                           &location,
                                           self.cur_scope);
             }
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index e812725e398..796850ad6f2 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -21,7 +21,7 @@ use syntax::{attr};
 use syntax::ast::{self, NodeId, DefId};
 use syntax::ast_util;
 use syntax::codemap::*;
-use syntax::parse::token::{self, get_ident, keywords};
+use syntax::parse::token::{self, keywords};
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::ty_to_string;
 
@@ -227,7 +227,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
                 Data::VariableData(VariableData {
                     id: item.id,
-                    name: get_ident(item.ident).to_string(),
+                    name: item.ident.to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
                     scope: self.enclosing_scope(item.id),
@@ -241,7 +241,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
                 Data::VariableData(VariableData {
                     id: item.id,
-                    name: get_ident(item.ident).to_string(),
+                    name: item.ident.to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
                     scope: self.enclosing_scope(item.id),
@@ -259,7 +259,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
                 Data::ModData(ModData {
                     id: item.id,
-                    name: get_ident(item.ident).to_string(),
+                    name: item.ident.to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
                     scope: self.enclosing_scope(item.id),
@@ -323,16 +323,15 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
     pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<VariableData> {
         match field.node.kind {
             ast::NamedField(ident, _) => {
-                let name = get_ident(ident);
                 let qualname = format!("::{}::{}",
                                        self.tcx.map.path_to_string(scope),
-                                       name);
+                                       ident);
                 let typ = self.tcx.node_types().get(&field.node.id).unwrap()
                                                .to_string();
                 let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
                 Some(VariableData {
                     id: field.node.id,
-                    name: get_ident(ident).to_string(),
+                    name: ident.to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
                     scope: scope,
@@ -404,7 +403,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             },
         };
 
-        let qualname = format!("{}::{}", qualname, &token::get_name(name));
+        let qualname = format!("{}::{}", qualname, name);
 
         let decl_id = self.tcx.trait_item_of_item(ast_util::local_def(id))
             .and_then(|new_id| {
@@ -420,7 +419,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
         FunctionData {
             id: id,
-            name: token::get_name(name).to_string(),
+            name: name.to_string(),
             qualname: qualname,
             declaration: decl_id,
             span: sub_span.unwrap(),
@@ -454,7 +453,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                             if f.name == ident.node.name {
                                 let sub_span = self.span_utils.span_for_last_ident(expr.span);
                                 return Some(Data::VariableRefData(VariableRefData {
-                                    name: get_ident(ident.node).to_string(),
+                                    name: ident.node.to_string(),
                                     span: sub_span.unwrap(),
                                     scope: self.enclosing_scope(expr.id),
                                     ref_id: f.id,
@@ -464,7 +463,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
                         self.tcx.sess.span_bug(expr.span,
                                                &format!("Couldn't find field {} on {:?}",
-                                                        &get_ident(ident.node), ty))
+                                                        ident.node, ty))
                     }
                     _ => {
                         debug!("Expected struct type, found {:?}", ty);
@@ -552,12 +551,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     scope: self.enclosing_scope(id),
                 }))
             }
-            def::DefMethod(decl_id, provenence) => {
+            def::DefMethod(decl_id) => {
                 let sub_span = self.span_utils.sub_span_for_meth_name(path.span);
                 let def_id = if decl_id.krate == ast::LOCAL_CRATE {
                     let ti = self.tcx.impl_or_trait_item(decl_id);
-                    match provenence {
-                        def::FromTrait(def_id) => {
+                    match ti.container() {
+                        ty::TraitContainer(def_id) => {
                             self.tcx.trait_items(def_id)
                                 .iter()
                                 .find(|mr| {
@@ -565,7 +564,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                                 })
                                 .map(|mr| mr.def_id())
                         }
-                        def::FromImpl(def_id) => {
+                        ty::ImplContainer(def_id) => {
                             let impl_items = self.tcx.impl_items.borrow();
                             Some(impl_items.get(&def_id)
                                            .unwrap()
@@ -626,7 +625,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                               parent: NodeId)
                               -> VariableRefData {
         let fields = self.tcx.lookup_struct_fields(struct_id);
-        let field_name = get_ident(field_ref.ident.node).to_string();
+        let field_name = field_ref.ident.node.to_string();
         for f in &fields {
             if f.name == field_ref.ident.node.name {
                 // We don't really need a sub-span here, but no harm done
@@ -700,7 +699,7 @@ impl<'v> Visitor<'v> for PathCollector {
             }
             ast::PatIdent(bm, ref path1, _) => {
                 debug!("PathCollector, visit ident in pat {}: {:?} {:?}",
-                       token::get_ident(path1.node),
+                       path1.node,
                        p.span,
                        path1.span);
                 let immut = match bm {
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 61e81d75607..907fe34215f 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -2032,6 +2032,23 @@ pub fn update_linkage(ccx: &CrateContext,
     }
 }
 
+fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &ast::Item) {
+    match attr::first_attr_value_str_by_name(&i.attrs,
+                                             "link_section") {
+        Some(sect) => {
+            if contains_null(&sect) {
+                ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`",
+                                            &sect));
+            }
+            unsafe {
+                let buf = CString::new(sect.as_bytes()).unwrap();
+                llvm::LLVMSetSection(llval, buf.as_ptr());
+            }
+        },
+        None => ()
+    }
+}
+
 pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
     let _icx = push_ctxt("trans_item");
 
@@ -2054,6 +2071,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
                 } else {
                     trans_fn(ccx, &**decl, &**body, llfn, empty_substs, item.id, &item.attrs);
                 }
+                set_global_section(ccx, llfn, item);
                 update_linkage(ccx, llfn, Some(item.id),
                                if is_origin { OriginalTranslation } else { InlinedCopy });
 
@@ -2103,6 +2121,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
           v.visit_expr(&**expr);
 
           let g = consts::trans_static(ccx, m, expr, item.id, &item.attrs);
+          set_global_section(ccx, g, item);
           update_linkage(ccx, g, Some(item.id), OriginalTranslation);
       },
       ast::ItemForeignMod(ref foreign_mod) => {
@@ -2171,6 +2190,12 @@ fn finish_register_fn(ccx: &CrateContext, sym: String, node_id: ast::NodeId,
             llvm::SetDLLStorageClass(llfn, llvm::DLLExportStorageClass);
         }
     }
+    if ccx.tcx().lang_items.eh_unwind_resume() == Some(def) {
+        llvm::SetLinkage(llfn, llvm::ExternalLinkage);
+        if ccx.use_dll_storage_attrs() {
+            llvm::SetDLLStorageClass(llfn, llvm::DLLExportStorageClass);
+        }
+    }
 }
 
 fn register_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
@@ -2381,21 +2406,6 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                 _ => ccx.sess().bug("get_item_val: weird result in table")
             };
 
-            match attr::first_attr_value_str_by_name(&i.attrs,
-                                                     "link_section") {
-                Some(sect) => {
-                    if contains_null(&sect) {
-                        ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`",
-                                                 &sect));
-                    }
-                    unsafe {
-                        let buf = CString::new(sect.as_bytes()).unwrap();
-                        llvm::LLVMSetSection(v, buf.as_ptr());
-                    }
-                },
-                None => ()
-            }
-
             v
         }
 
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 0f75c1f8ab6..a60217be409 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -159,16 +159,27 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                 let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
                 Callee { bcx: bcx, data: Intrinsic(def_id.node, substs), ty: expr_ty }
             }
-            def::DefFn(did, _) | def::DefMethod(did, def::FromImpl(_)) => {
+            def::DefFn(did, _) => {
                 fn_callee(bcx, trans_fn_ref(bcx.ccx(), did, ExprId(ref_expr.id),
                                             bcx.fcx.param_substs))
             }
-            def::DefMethod(meth_did, def::FromTrait(trait_did)) => {
-                fn_callee(bcx, meth::trans_static_method_callee(bcx.ccx(),
-                                                                meth_did,
-                                                                trait_did,
-                                                                ref_expr.id,
-                                                                bcx.fcx.param_substs))
+            def::DefMethod(meth_did) => {
+                let method_item = bcx.tcx().impl_or_trait_item(meth_did);
+                let fn_datum = match method_item.container() {
+                    ty::ImplContainer(_) => {
+                        trans_fn_ref(bcx.ccx(), meth_did,
+                                     ExprId(ref_expr.id),
+                                     bcx.fcx.param_substs)
+                    }
+                    ty::TraitContainer(trait_did) => {
+                        meth::trans_static_method_callee(bcx.ccx(),
+                                                         meth_did,
+                                                         trait_did,
+                                                         ref_expr.id,
+                                                         bcx.fcx.param_substs)
+                    }
+                };
+                fn_callee(bcx, fn_datum)
             }
             def::DefVariant(tid, vid, _) => {
                 let vinfo = bcx.tcx().enum_variant_with_id(tid, vid);
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index b4b0472512e..5e472e45775 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -846,6 +846,8 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
 
         debug!("get_or_create_landing_pad");
 
+        self.inject_unwind_resume_hook();
+
         // Check if a landing pad block exists; if not, create one.
         {
             let mut scopes = self.scopes.borrow_mut();
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index 9478c197a44..d0b81b38ab7 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -561,6 +561,55 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
             }
         }
     }
+
+    /// By default, LLVM lowers `resume` instructions into calls to `_Unwind_Resume`
+    /// defined in libgcc, however, unlike personality routines, there is no easy way to
+    /// override that symbol.  This method injects a local-scoped `_Unwind_Resume` function
+    /// which immediately defers to the user-defined `eh_unwind_resume` lang item.
+    pub fn inject_unwind_resume_hook(&self) {
+        let ccx = self.ccx;
+        if !ccx.sess().target.target.options.custom_unwind_resume ||
+           ccx.unwind_resume_hooked().get() {
+            return;
+        }
+
+        let new_resume = match ccx.tcx().lang_items.eh_unwind_resume() {
+            Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0), &self.param_substs).val,
+            None => {
+                let fty = Type::variadic_func(&[], &Type::void(self.ccx));
+                declare::declare_cfn(self.ccx, "rust_eh_unwind_resume", fty,
+                                     self.ccx.tcx().mk_nil())
+            }
+        };
+
+        unsafe {
+            let resume_type = Type::func(&[Type::i8(ccx).ptr_to()], &Type::void(ccx));
+            let old_resume = llvm::LLVMAddFunction(ccx.llmod(),
+                                                   "_Unwind_Resume\0".as_ptr() as *const _,
+                                                   resume_type.to_ref());
+            llvm::SetLinkage(old_resume, llvm::InternalLinkage);
+            let llbb = llvm::LLVMAppendBasicBlockInContext(ccx.llcx(),
+                                                           old_resume,
+                                                           "\0".as_ptr() as *const _);
+            let builder = ccx.builder();
+            builder.position_at_end(llbb);
+            builder.call(new_resume, &[llvm::LLVMGetFirstParam(old_resume)], None);
+            builder.unreachable(); // it should never return
+
+            // Until DwarfEHPrepare pass has run, _Unwind_Resume is not referenced by any live code
+            // and is subject to dead code elimination.  Here we add _Unwind_Resume to @llvm.globals
+            // to prevent that.
+            let i8p_ty = Type::i8p(ccx);
+            let used_ty = Type::array(&i8p_ty, 1);
+            let used = llvm::LLVMAddGlobal(ccx.llmod(), used_ty.to_ref(),
+                                           "llvm.used\0".as_ptr() as *const _);
+            let old_resume = llvm::LLVMConstBitCast(old_resume, i8p_ty.to_ref());
+            llvm::LLVMSetInitializer(used, C_array(i8p_ty, &[old_resume]));
+            llvm::SetLinkage(used, llvm::AppendingLinkage);
+            llvm::LLVMSetSection(used, "llvm.metadata\0".as_ptr() as *const _)
+        }
+        ccx.unwind_resume_hooked().set(true);
+    }
 }
 
 // Basic block context.  We create a block context for each basic block
@@ -617,7 +666,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
     pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
 
     pub fn name(&self, name: ast::Name) -> String {
-        token::get_name(name).to_string()
+        name.to_string()
     }
 
     pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index bd9c4a17177..71ba4d73dac 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -229,7 +229,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ast::ExprPath(..) => {
             let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
             match def {
-                def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
+                def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
                     if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
                         debug!("get_const_expr_as_global ({:?}): found const {:?}",
                                expr.id, def_id);
@@ -802,7 +802,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 def::DefFn(..) | def::DefMethod(..) => {
                     expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
                 }
-                def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
+                def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
                     const_deref_ptr(cx, get_const_val(cx, def_id, e))
                 }
                 def::DefVariant(enum_did, variant_did, _) => {
@@ -846,9 +846,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let def = cx.tcx().def_map.borrow()[&callee.id].full_def();
             let arg_vals = map_list(args);
             match def {
-                def::DefFn(did, _) | def::DefMethod(did, _) => {
+                def::DefFn(did, _) | def::DefMethod(did) => {
                     const_fn_call(cx, ExprId(callee.id), did, &arg_vals, param_substs)
-                },
+                }
                 def::DefStruct(_) => {
                     if ety.is_simd(cx.tcx()) {
                         C_vector(&arg_vals[..])
@@ -856,7 +856,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         let repr = adt::represent_type(cx, ety);
                         adt::trans_const(cx, &*repr, 0, &arg_vals[..])
                     }
-                },
+                }
                 def::DefVariant(enum_did, variant_did, _) => {
                     let repr = adt::represent_type(cx, ety);
                     let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did);
@@ -864,14 +864,14 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                      &*repr,
                                      vinfo.disr_val,
                                      &arg_vals[..])
-                },
+                }
                 _ => cx.sess().span_bug(e.span, "expected a struct, variant, or const fn def"),
             }
         },
         ast::ExprMethodCall(_, _, ref args) => {
             let arg_vals = map_list(args);
             let method_call = ty::MethodCall::expr(e.id);
-              let method_did = cx.tcx().tables.borrow().method_map[&method_call].def_id;
+            let method_did = cx.tcx().tables.borrow().method_map[&method_call].def_id;
             const_fn_call(cx, MethodCallKey(method_call),
                           method_did, &arg_vals, param_substs)
         },
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 235538f62c2..b7b7b28a42b 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -146,6 +146,7 @@ pub struct LocalCrateContext<'tcx> {
 
     eh_personality: RefCell<Option<ValueRef>>,
     rust_try_fn: RefCell<Option<ValueRef>>,
+    unwind_resume_hooked: Cell<bool>,
 
     intrinsics: RefCell<FnvHashMap<&'static str, ValueRef>>,
 
@@ -466,6 +467,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
                 dbg_cx: dbg_cx,
                 eh_personality: RefCell::new(None),
                 rust_try_fn: RefCell::new(None),
+                unwind_resume_hooked: Cell::new(false),
                 intrinsics: RefCell::new(FnvHashMap()),
                 n_llvm_insns: Cell::new(0),
                 trait_cache: RefCell::new(FnvHashMap()),
@@ -735,6 +737,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.rust_try_fn
     }
 
+    pub fn unwind_resume_hooked<'a>(&'a self) -> &'a Cell<bool> {
+        &self.local.unwind_resume_hooked
+    }
+
     fn intrinsics<'a>(&'a self) -> &'a RefCell<FnvHashMap<&'static str, ValueRef>> {
         &self.local.intrinsics
     }
diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs
index 77822397e89..b8feecd0a55 100644
--- a/src/librustc_trans/trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/trans/debuginfo/metadata.rs
@@ -26,7 +26,6 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
 use metadata::csearch;
 use middle::pat_util;
 use middle::subst::{self, Substs};
-use middle::infer;
 use rustc::ast_map;
 use trans::{type_of, adt, machine, monomorphize};
 use trans::common::{self, CrateContext, FunctionContext, Block};
@@ -287,12 +286,18 @@ impl<'tcx> TypeMap<'tcx> {
                     }
                 }
             },
-            ty::TyClosure(def_id, ref substs) => {
-                let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
-                let closure_ty = infcx.closure_type(def_id, substs);
-                self.get_unique_type_id_of_closure_type(cx,
-                                                        closure_ty,
-                                                        &mut unique_type_id);
+            ty::TyClosure(_, ref substs) if substs.upvar_tys.is_empty() => {
+                push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
+            },
+            ty::TyClosure(_, ref substs) => {
+                unique_type_id.push_str("closure ");
+                for upvar_type in &substs.upvar_tys {
+                    let upvar_type_id =
+                        self.get_unique_type_id_of_type(cx, upvar_type);
+                    let upvar_type_id =
+                        self.get_unique_type_id_as_string(upvar_type_id);
+                    unique_type_id.push_str(&upvar_type_id[..]);
+                }
             },
             _ => {
                 cx.sess().bug(&format!("get_unique_type_id_of_type() - unexpected type: {:?}",
@@ -361,49 +366,6 @@ impl<'tcx> TypeMap<'tcx> {
         }
     }
 
-    fn get_unique_type_id_of_closure_type<'a>(&mut self,
-                                              cx: &CrateContext<'a, 'tcx>,
-                                              closure_ty: ty::ClosureTy<'tcx>,
-                                              unique_type_id: &mut String) {
-        let ty::ClosureTy { unsafety,
-                            ref sig,
-                            abi: _ } = closure_ty;
-
-        if unsafety == ast::Unsafety::Unsafe {
-            unique_type_id.push_str("unsafe ");
-        }
-
-        unique_type_id.push_str("|");
-
-        let sig = cx.tcx().erase_late_bound_regions(sig);
-
-        for &parameter_type in &sig.inputs {
-            let parameter_type_id =
-                self.get_unique_type_id_of_type(cx, parameter_type);
-            let parameter_type_id =
-                self.get_unique_type_id_as_string(parameter_type_id);
-            unique_type_id.push_str(&parameter_type_id[..]);
-            unique_type_id.push(',');
-        }
-
-        if sig.variadic {
-            unique_type_id.push_str("...");
-        }
-
-        unique_type_id.push_str("|->");
-
-        match sig.output {
-            ty::FnConverging(ret_ty) => {
-                let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
-                let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-                unique_type_id.push_str(&return_type_id[..]);
-            }
-            ty::FnDiverging => {
-                unique_type_id.push_str("!");
-            }
-        }
-    }
-
     // Get the UniqueTypeId for an enum variant. Enum variants are not really
     // types of their own, so they need special handling. We still need a
     // UniqueTypeId for them, since to debuginfo they *are* real types.
@@ -1152,7 +1114,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
             let name = if field.name == special_idents::unnamed_field.name {
                 format!("__{}", i)
             } else {
-                token::get_name(field.name).to_string()
+                field.name.to_string()
             };
 
             let offset = if self.is_simd {
@@ -1307,7 +1269,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                             describe_enum_variant(cx,
                                                   self.enum_type,
                                                   struct_def,
-                                                  &*(*self.variants)[i],
+                                                  &*self.variants[i],
                                                   discriminant_info,
                                                   self.containing_scope,
                                                   self.span);
@@ -1340,7 +1302,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                         describe_enum_variant(cx,
                                               self.enum_type,
                                               struct_def,
-                                              &*(*self.variants)[0],
+                                              &*self.variants[0],
                                               NoDiscriminant,
                                               self.containing_scope,
                                               self.span);
@@ -1369,8 +1331,8 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                 // DWARF representation of enums uniform.
 
                 // First create a description of the artificial wrapper struct:
-                let non_null_variant = &(*self.variants)[non_null_variant_index as usize];
-                let non_null_variant_name = token::get_name(non_null_variant.name);
+                let non_null_variant = &self.variants[non_null_variant_index as usize];
+                let non_null_variant_name = non_null_variant.name.as_str();
 
                 // The llvm type and metadata of the pointer
                 let non_null_llvm_type = type_of::type_of(cx, nnty);
@@ -1385,7 +1347,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                 // MemberDescription of the struct's single field.
                 let sole_struct_member_description = MemberDescription {
                     name: match non_null_variant.arg_names {
-                        Some(ref names) => token::get_name(names[0]).to_string(),
+                        Some(ref names) => names[0].to_string(),
                         None => "__0".to_string()
                     },
                     llvm_type: non_null_llvm_type,
@@ -1415,7 +1377,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                 // Encode the information about the null variant in the union
                 // member's name.
                 let null_variant_index = (1 - non_null_variant_index) as usize;
-                let null_variant_name = token::get_name((*self.variants)[null_variant_index].name);
+                let null_variant_name = self.variants[null_variant_index].name;
                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
                                                 0,
                                                 null_variant_name);
@@ -1440,7 +1402,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                     describe_enum_variant(cx,
                                           self.enum_type,
                                           struct_def,
-                                          &*(*self.variants)[nndiscr as usize],
+                                          &*self.variants[nndiscr as usize],
                                           OptimizedDiscriminant,
                                           self.containing_scope,
                                           self.span);
@@ -1456,7 +1418,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                 // Encode the information about the null variant in the union
                 // member's name.
                 let null_variant_index = (1 - nndiscr) as usize;
-                let null_variant_name = token::get_name((*self.variants)[null_variant_index].name);
+                let null_variant_name = self.variants[null_variant_index].name;
                 let discrfield = discrfield.iter()
                                            .skip(1)
                                            .map(|x| x.to_string())
@@ -1534,18 +1496,17 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       struct_def.packed);
     // Could do some consistency checks here: size, align, field count, discr type
 
-    let variant_name = token::get_name(variant_info.name);
-    let variant_name = &variant_name;
+    let variant_name = variant_info.name.as_str();
     let unique_type_id = debug_context(cx).type_map
                                           .borrow_mut()
                                           .get_unique_type_id_of_enum_variant(
                                               cx,
                                               enum_type,
-                                              variant_name);
+                                              &variant_name);
 
     let metadata_stub = create_struct_stub(cx,
                                            variant_llvm_type,
-                                           variant_name,
+                                           &variant_name,
                                            unique_type_id,
                                            containing_scope);
 
@@ -1553,7 +1514,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let mut arg_names: Vec<_> = match variant_info.arg_names {
         Some(ref names) => {
             names.iter()
-                 .map(|&name| token::get_name(name).to_string())
+                 .map(|name| name.to_string())
                  .collect()
         }
         None => {
@@ -1609,7 +1570,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let enumerators_metadata: Vec<DIDescriptor> = variants
         .iter()
         .map(|v| {
-            let token = token::get_name(v.name);
+            let token = v.name.as_str();
             let name = CString::new(token.as_bytes()).unwrap();
             unsafe {
                 llvm::LLVMDIBuilderCreateEnumerator(
@@ -1723,7 +1684,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             csearch::get_item_path(cx.tcx(), def_id).last().unwrap().name()
         };
 
-        token::get_name(name)
+        name.as_str()
     }
 }
 
@@ -1907,7 +1868,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     let variable_type = cx.tcx().node_id_to_type(node_id);
     let type_metadata = type_metadata(cx, variable_type, span);
     let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
-    let var_name = token::get_name(name).to_string();
+    let var_name = name.to_string();
     let linkage_name =
         namespace_node.mangled_name_of_contained_item(&var_name[..]);
     let var_scope = namespace_node.scope;
diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs
index 8e4e0aaa75f..97baaa2e74b 100644
--- a/src/librustc_trans/trans/debuginfo/mod.rs
+++ b/src/librustc_trans/trans/debuginfo/mod.rs
@@ -333,7 +333,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     // Get_template_parameters() will append a `<...>` clause to the function
     // name if necessary.
-    let mut function_name = String::from(&*token::get_name(name));
+    let mut function_name = name.to_string();
     let template_parameters = get_template_parameters(cx,
                                                       generics,
                                                       param_substs,
@@ -494,7 +494,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                               actual_self_type,
                                                               codemap::DUMMY_SP);
 
-                let name = token::get_name(special_idents::type_self.name);
+                let name = special_idents::type_self.name.as_str();
 
                 let name = CString::new(name.as_bytes()).unwrap();
                 let param_metadata = unsafe {
@@ -529,8 +529,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             // Again, only create type information if full debuginfo is enabled
             if cx.sess().opts.debuginfo == FullDebugInfo {
                 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
-                let ident = token::get_ident(ident);
-                let name = CString::new(ident.as_bytes()).unwrap();
+                let name = CString::new(ident.name.as_str().as_bytes()).unwrap();
                 let param_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
@@ -563,7 +562,6 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let filename = span_start(cx, span).file.name.clone();
     let file_metadata = file_metadata(cx, &filename[..]);
 
-    let name = token::get_name(variable_name);
     let loc = span_start(cx, span);
     let type_metadata = type_metadata(cx, variable_type, span);
 
@@ -573,7 +571,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         CapturedVariable => (0, DW_TAG_auto_variable)
     };
 
-    let name = CString::new(name.as_bytes()).unwrap();
+    let name = CString::new(variable_name.as_str().as_bytes()).unwrap();
     match (variable_access, &[][..]) {
         (DirectVariable { alloca }, address_operations) |
         (IndirectVariable {alloca, address_operations}, _) => {
diff --git a/src/librustc_trans/trans/debuginfo/namespace.rs b/src/librustc_trans/trans/debuginfo/namespace.rs
index 8b33acdee8e..fa92fb0baae 100644
--- a/src/librustc_trans/trans/debuginfo/namespace.rs
+++ b/src/librustc_trans/trans/debuginfo/namespace.rs
@@ -36,14 +36,14 @@ impl NamespaceTreeNode {
                 Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
                 None => {}
             }
-            let string = token::get_name(node.name);
-            output.push_str(&format!("{}", string.len()));
+            let string = node.name.as_str();
+            output.push_str(&string.len().to_string());
             output.push_str(&string);
         }
 
         let mut name = String::from("_ZN");
         fill_nested(self, &mut name);
-        name.push_str(&format!("{}", item_name.len()));
+        name.push_str(&item_name.len().to_string());
         name.push_str(item_name);
         name.push('E');
         name
@@ -93,7 +93,7 @@ pub fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<Namespace
                         Some(ref node) => node.scope,
                         None => ptr::null_mut()
                     };
-                    let namespace_name = token::get_name(name);
+                    let namespace_name = name.as_str();
                     let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
                     let scope = unsafe {
                         llvm::LLVMDIBuilderCreateNameSpace(
diff --git a/src/librustc_trans/trans/debuginfo/type_names.rs b/src/librustc_trans/trans/debuginfo/type_names.rs
index b912acb90a2..4835cfc4a25 100644
--- a/src/librustc_trans/trans/debuginfo/type_names.rs
+++ b/src/librustc_trans/trans/debuginfo/type_names.rs
@@ -17,7 +17,6 @@ use middle::subst::{self, Substs};
 use middle::ty::{self, Ty};
 
 use syntax::ast;
-use syntax::parse::token;
 
 
 // Compute the name of the type as it should be stored in debuginfo. Does not do
@@ -179,8 +178,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
                 let mut path_element_count = 0;
                 for path_element in path {
-                    let name = token::get_name(path_element.name());
-                    output.push_str(&name);
+                    output.push_str(&path_element.name().as_str());
                     output.push_str("::");
                     path_element_count += 1;
                 }
@@ -192,10 +190,8 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 output.pop();
                 output.pop();
             } else {
-                let name = token::get_name(path.last()
-                                               .expect("debuginfo: Empty item path?")
-                                               .name());
-                output.push_str(&name);
+                let name = path.last().expect("debuginfo: Empty item path?").name();
+                output.push_str(&name.as_str());
             }
         });
     }
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 35e3c96d09c..619447df3c5 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -1293,14 +1293,22 @@ pub fn trans_def_fn_unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     match def {
         def::DefFn(did, _) |
-        def::DefStruct(did) | def::DefVariant(_, did, _) |
-        def::DefMethod(did, def::FromImpl(_)) => {
+        def::DefStruct(did) | def::DefVariant(_, did, _) => {
             callee::trans_fn_ref(ccx, did, ExprId(ref_expr.id), param_substs)
         }
-        def::DefMethod(impl_did, def::FromTrait(trait_did)) => {
-            meth::trans_static_method_callee(ccx, impl_did,
-                                             trait_did, ref_expr.id,
-                                             param_substs)
+        def::DefMethod(method_did) => {
+            match ccx.tcx().impl_or_trait_item(method_did).container() {
+                ty::ImplContainer(_) => {
+                    callee::trans_fn_ref(ccx, method_did,
+                                         ExprId(ref_expr.id),
+                                         param_substs)
+                }
+                ty::TraitContainer(trait_did) => {
+                    meth::trans_static_method_callee(ccx, method_did,
+                                                     trait_did, ref_expr.id,
+                                                     param_substs)
+                }
+            }
         }
         _ => {
             ccx.tcx().sess.span_bug(ref_expr.span, &format!(
@@ -2325,7 +2333,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => {
             bcx.tcx().sess.span_bug(
                 expr.span,
-                &format!("deref invoked on expr of illegal type {:?}",
+                &format!("deref invoked on expr of invalid type {:?}",
                         datum.ty));
         }
     };
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index e102e3cd062..cafc0be74ba 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -37,7 +37,6 @@ use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi};
 use syntax::abi::{RustIntrinsic, Rust, RustCall, Stdcall, Fastcall, System};
 use syntax::codemap::Span;
 use syntax::parse::token::{InternedString, special_idents};
-use syntax::parse::token;
 use syntax::ast;
 use syntax::attr;
 use syntax::print::pprust;
@@ -902,7 +901,7 @@ pub fn link_name(i: &ast::ForeignItem) -> InternedString {
         Some(ln) => ln.clone(),
         None => match weak_lang_items::link_name(&i.attrs) {
             Some(name) => name,
-            None => token::get_ident(i.ident),
+            None => i.ident.name.as_str(),
         }
     }
 }
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index e78218fd10d..0400771dff1 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -16,6 +16,7 @@ use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeK
 use middle::subst;
 use middle::subst::FnSpace;
 use trans::adt;
+use trans::attributes;
 use trans::base::*;
 use trans::build::*;
 use trans::callee;
@@ -39,7 +40,7 @@ use syntax::ast;
 use syntax::parse::token;
 
 pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
-    let name = match &token::get_ident(item.ident)[..] {
+    let name = match &*item.ident.name.as_str() {
         "sqrtf32" => "llvm.sqrt.f32",
         "sqrtf64" => "llvm.sqrt.f64",
         "powif32" => "llvm.powi.f32",
@@ -171,10 +172,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         _ => panic!("expected bare_fn in trans_intrinsic_call")
     };
     let foreign_item = tcx.map.expect_foreign_item(node);
-    let name = token::get_ident(foreign_item.ident);
+    let name = foreign_item.ident.name.as_str();
 
     // For `transmute` we can just trans the input expr directly into dest
-    if &name[..] == "transmute" {
+    if name == "transmute" {
         let llret_ty = type_of::type_of(ccx, ret_ty.unwrap());
         match args {
             callee::ArgExprs(arg_exprs) => {
@@ -271,7 +272,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     // (the first argument) and then trans the source value (the
     // second argument) directly into the resulting destination
     // address.
-    if &name[..] == "move_val_init" {
+    if name == "move_val_init" {
         if let callee::ArgExprs(ref exprs) = args {
             let (dest_expr, source_expr) = if exprs.len() != 2 {
                 ccx.sess().bug("expected two exprs as arguments for `move_val_init` intrinsic");
@@ -354,7 +355,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean();
 
     // These are the only intrinsic functions that diverge.
-    if &name[..] == "abort" {
+    if name == "abort" {
         let llfn = ccx.get_intrinsic(&("llvm.trap"));
         Call(bcx, llfn, &[], None, call_debug_location);
         fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
@@ -387,7 +388,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     };
 
     let simple = get_simple_intrinsic(ccx, &*foreign_item);
-    let llval = match (simple, &name[..]) {
+    let llval = match (simple, &*name) {
         (Some(llfn), _) => {
             Call(bcx, llfn, &llargs, None, call_debug_location)
         }
@@ -1159,26 +1160,14 @@ fn trans_msvc_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 // of exceptions (e.g. the normal semantics of LLVM's landingpad and invoke
 // instructions).
 //
-// This translation is a little surprising for two reasons:
+// This translation is a little surprising because
+// we always call a shim function instead of inlining the call to `invoke`
+// manually here. This is done because in LLVM we're only allowed to have one
+// personality per function definition. The call to the `try` intrinsic is
+// being inlined into the function calling it, and that function may already
+// have other personality functions in play. By calling a shim we're
+// guaranteed that our shim will have the right personality function.
 //
-// 1. We always call a shim function instead of inlining the call to `invoke`
-//    manually here. This is done because in LLVM we're only allowed to have one
-//    personality per function definition. The call to the `try` intrinsic is
-//    being inlined into the function calling it, and that function may already
-//    have other personality functions in play. By calling a shim we're
-//    guaranteed that our shim will have the right personality function.
-//
-// 2. Instead of making one shim (explained above), we make two shims! The
-//    reason for this has to do with the technical details about the
-//    implementation of unwinding in the runtime, but the tl;dr; is that the
-//    outer shim's personality function says "catch rust exceptions" and the
-//    inner shim's landing pad will not `resume` the exception being thrown.
-//    This means that the outer shim's landing pad is never run and the inner
-//    shim's return value is the return value of the whole call.
-//
-// The double-shim aspect is currently done for implementation ease on the
-// runtime side of things, and more info can be found in
-// src/libstd/rt/unwind/gcc.rs.
 fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                              func: ValueRef,
                              data: ValueRef,
@@ -1188,108 +1177,63 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let ccx = bcx.ccx();
         let dloc = DebugLoc::None;
 
-        // Type indicator for the exception being thrown, not entirely sure
-        // what's going on here but it's what all the examples in LLVM use.
-        let lpad_ty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)],
-                                    false);
+        // Translates the shims described above:
+        //
+        //   bcx:
+        //      invoke %func(%args...) normal %normal unwind %catch
+        //
+        //   normal:
+        //      ret null
+        //
+        //   catch:
+        //      (ptr, _) = landingpad
+        //      ret ptr
 
-        // Define the "inner try" shim
-        let rust_try_inner = declare::define_internal_rust_fn(ccx,
-                                                              "__rust_try_inner",
-                                                              try_fn_ty);
-        trans_rust_try(ccx, rust_try_inner, lpad_ty, bcx.fcx.eh_personality(),
-                       output, dloc, &mut |bcx, then, catch| {
-            let func = llvm::get_param(rust_try_inner, 0);
-            let data = llvm::get_param(rust_try_inner, 1);
-            Invoke(bcx, func, &[data], then.llbb, catch.llbb, None, dloc);
-            C_null(Type::i8p(ccx))
-        });
-
-        // Define the "outer try" shim.
-        let rust_try = declare::define_internal_rust_fn(ccx, "__rust_try",
-                                                        try_fn_ty);
+        let rust_try = declare::define_internal_rust_fn(ccx, "__rust_try", try_fn_ty);
+        attributes::emit_uwtable(rust_try, true);
         let catch_pers = match bcx.tcx().lang_items.eh_personality_catch() {
             Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0),
                                               bcx.fcx.param_substs).val,
             None => bcx.tcx().sess.bug("eh_personality_catch not defined"),
         };
-        trans_rust_try(ccx, rust_try, lpad_ty, catch_pers, output, dloc,
-                       &mut |bcx, then, catch| {
-            let func = llvm::get_param(rust_try, 0);
-            let data = llvm::get_param(rust_try, 1);
-            Invoke(bcx, rust_try_inner, &[func, data], then.llbb, catch.llbb,
-                   None, dloc)
-        });
-        return rust_try
-    });
 
-    // Note that no invoke is used here because by definition this function
-    // can't panic (that's what it's catching).
-    let ret = Call(bcx, llfn, &[func, data], None, dloc);
-    Store(bcx, ret, dest);
-    return bcx;
-
-    // Translates both the inner and outer shims described above. The only
-    // difference between these two is the function invoked and the personality
-    // involved, so a common routine is shared.
-    //
-    //   bcx:
-    //      invoke %func(%args...) normal %normal unwind %unwind
-    //
-    //   normal:
-    //      ret null
-    //
-    //   unwind:
-    //      (ptr, _) = landingpad
-    //      br (ptr != null), done, reraise
-    //
-    //   done:
-    //      ret ptr
-    //
-    //   reraise:
-    //      resume
-    //
-    // Note that the branch checking for `null` here isn't actually necessary,
-    // it's just an unfortunate hack to make sure that LLVM doesn't optimize too
-    // much. If this were not present, then LLVM would correctly deduce that our
-    // inner shim should be tagged with `nounwind` (as it catches all
-    // exceptions) and then the outer shim's `invoke` will be translated to just
-    // a simple call, destroying that entry for the personality function.
-    //
-    // To ensure that both shims always have an `invoke` this check against null
-    // confuses LLVM enough to the point that it won't infer `nounwind` and
-    // we'll proceed as normal.
-    fn trans_rust_try<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                                llfn: ValueRef,
-                                lpad_ty: Type,
-                                personality: ValueRef,
-                                output: ty::FnOutput<'tcx>,
-                                dloc: DebugLoc,
-                                invoke: &mut FnMut(Block, Block, Block) -> ValueRef) {
         let (fcx, block_arena);
         block_arena = TypedArena::new();
-        fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false,
+        fcx = new_fn_ctxt(ccx, rust_try, ast::DUMMY_NODE_ID, false,
                           output, ccx.tcx().mk_substs(Substs::trans_empty()),
                           None, &block_arena);
         let bcx = init_function(&fcx, true, output);
         let then = bcx.fcx.new_temp_block("then");
         let catch = bcx.fcx.new_temp_block("catch");
-        let reraise = bcx.fcx.new_temp_block("reraise");
-        let catch_return = bcx.fcx.new_temp_block("catch-return");
 
-        let invoke_ret = invoke(bcx, then, catch);
-        Ret(then, invoke_ret, dloc);
-        let vals = LandingPad(catch, lpad_ty, personality, 1);
+        let func = llvm::get_param(rust_try, 0);
+        let data = llvm::get_param(rust_try, 1);
+        Invoke(bcx, func, &[data], then.llbb, catch.llbb, None, dloc);
+        Ret(then, C_null(Type::i8p(ccx)), dloc);
+
+        // Type indicator for the exception being thrown.
+        // The first value in this tuple is a pointer to the exception object being thrown.
+        // The second value is a "selector" indicating which of the landing pad clauses
+        // the exception's type had been matched to.  rust_try ignores the selector.
+        let lpad_ty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)],
+                                    false);
+        let vals = LandingPad(catch, lpad_ty, catch_pers, 1);
         AddClause(catch, vals, C_null(Type::i8p(ccx)));
         let ptr = ExtractValue(catch, vals, 0);
-        let valid = ICmp(catch, llvm::IntNE, ptr, C_null(Type::i8p(ccx)), dloc);
-        CondBr(catch, valid, catch_return.llbb, reraise.llbb, dloc);
-        Ret(catch_return, ptr, dloc);
-        Resume(reraise, vals);
-    }
+        Ret(catch, ptr, dloc);
+        fcx.cleanup();
+
+        return rust_try
+    });
+
+    // Note that no invoke is used here because by definition this function
+    // can't panic (that's what it's catching).
+    let ret = Call(bcx, llfn, &[func, data], None, dloc);
+    Store(bcx, ret, dest);
+    return bcx;
 }
 
-// Helper to generate the `Ty` associated with `rust_Try`
+// Helper to generate the `Ty` associated with `rust_try`
 fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
                              f: &mut FnMut(Ty<'tcx>,
                                            ty::FnOutput<'tcx>) -> ValueRef)
@@ -1299,8 +1243,7 @@ fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
         return llfn
     }
 
-    // Define the types up front for the signatures of the rust_try and
-    // rust_try_inner functions.
+    // Define the type up front for the signature of the rust_try function.
     let tcx = ccx.tcx();
     let i8p = tcx.mk_mut_ptr(tcx.types.i8);
     let fn_ty = tcx.mk_bare_fn(ty::BareFnTy {
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 4a549d9c24c..499e0911da8 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -39,7 +39,6 @@ use trans::type_of::*;
 use middle::ty::{self, Ty, HasTypeFlags};
 use middle::ty::MethodCall;
 
-use syntax::parse::token;
 use syntax::{ast, attr, visit};
 use syntax::codemap::DUMMY_SP;
 use syntax::ptr::P;
@@ -175,7 +174,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         csearch::get_item_path(tcx, method_id).last().unwrap().name()
     };
     debug!("trans_static_method_callee: method_id={:?}, expr_id={}, \
-            name={}", method_id, expr_id, token::get_name(mname));
+            name={}", method_id, expr_id, mname);
 
     // Find the substitutions for the fn itself. This includes
     // type parameters that belong to the trait but also some that
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 332b84bfc7b..a2c968a290b 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -69,6 +69,7 @@ use util::nodemap::FnvHashSet;
 use std::slice;
 use syntax::{abi, ast, ast_util};
 use syntax::codemap::{Span, Pos};
+use syntax::feature_gate::emit_feature_err;
 use syntax::parse::token;
 use syntax::print::pprust;
 
@@ -791,12 +792,11 @@ fn create_substs_for_ast_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
             // For now, require that parenthetical notation be used
             // only with `Fn()` etc.
             if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
-                span_err!(this.tcx().sess, span, E0215,
-                                         "angle-bracket notation is not stable when \
-                                         used with the `Fn` family of traits, use parentheses");
-                fileline_help!(this.tcx().sess, span,
-                           "add `#![feature(unboxed_closures)]` to \
-                            the crate attributes to enable");
+                emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
+                                 "unboxed_closures", span,
+                                 "\
+                    the precise format of `Fn`-family traits' type parameters is \
+                    subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead");
             }
 
             convert_angle_bracketed_parameters(this, rscope, span, &trait_def.generics, data)
@@ -805,12 +805,10 @@ fn create_substs_for_ast_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
             // For now, require that parenthetical notation be used
             // only with `Fn()` etc.
             if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
-                span_err!(this.tcx().sess, span, E0216,
-                                         "parenthetical notation is only stable when \
-                                         used with the `Fn` family of traits");
-                fileline_help!(this.tcx().sess, span,
-                           "add `#![feature(unboxed_closures)]` to \
-                            the crate attributes to enable");
+                emit_feature_err(&this.tcx().sess.parse_sess.span_diagnostic,
+                                 "unboxed_closures", span,
+                                 "\
+                    parenthetical notation is only stable when used with `Fn`-family traits");
             }
 
             convert_parenthesized_parameters(this, rscope, span, &trait_def.generics, data)
@@ -903,7 +901,7 @@ fn ast_type_binding_to_poly_projection_predicate<'tcx>(
     let candidate = try!(one_bound_for_assoc_type(tcx,
                                                   candidates,
                                                   &trait_ref.to_string(),
-                                                  &token::get_name(binding.item_name),
+                                                  &binding.item_name.as_str(),
                                                   binding.span));
 
     Ok(ty::Binder(ty::ProjectionPredicate {             // <-------------------------+
@@ -1150,8 +1148,8 @@ fn find_bound_for_assoc_item<'tcx>(this: &AstConv<'tcx>,
 
     one_bound_for_assoc_type(tcx,
                              suitable_bounds,
-                             &token::get_name(ty_param_name),
-                             &token::get_name(assoc_name),
+                             &ty_param_name.as_str(),
+                             &assoc_name.as_str(),
                              span)
 }
 
@@ -1236,7 +1234,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             match one_bound_for_assoc_type(tcx,
                                            candidates,
                                            "Self",
-                                           &token::get_name(assoc_name),
+                                           &assoc_name.as_str(),
                                            span) {
                 Ok(bound) => bound,
                 Err(ErrorReported) => return (tcx.types.err, ty_path_def),
@@ -1269,7 +1267,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                              span,
                                              &ty.to_string(),
                                              "Trait",
-                                             &token::get_name(assoc_name));
+                                             &assoc_name.as_str());
             return (tcx.types.err, ty_path_def);
         }
     };
@@ -1320,7 +1318,7 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
                                          span,
                                          "Type",
                                          &path_str,
-                                         &token::get_ident(item_segment.identifier));
+                                         &item_segment.identifier.name.as_str());
         return tcx.types.err;
     };
 
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index c4b31d578db..b853a5300e2 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -27,7 +27,6 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::{Span, Spanned};
-use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::ptr::P;
 
@@ -736,10 +735,10 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             Occupied(occupied) => {
                 span_err!(tcx.sess, span, E0025,
                     "field `{}` bound multiple times in the pattern",
-                    token::get_ident(field.ident));
+                    field.ident);
                 span_note!(tcx.sess, *occupied.get(),
                     "field `{}` previously bound here",
-                    token::get_ident(field.ident));
+                    field.ident);
                 tcx.types.err
             }
             Vacant(vacant) => {
@@ -749,7 +748,7 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                         span_err!(tcx.sess, span, E0026,
                             "struct `{}` does not have a field named `{}`",
                             tcx.item_path_str(struct_id),
-                            token::get_ident(field.ident));
+                            field.ident);
                         tcx.types.err
                     })
             }
@@ -767,7 +766,7 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             .filter(|field| !used_fields.contains_key(&field.name)) {
             span_err!(tcx.sess, span, E0027,
                 "pattern does not mention field `{}`",
-                token::get_name(field.name));
+                field.name);
         }
     }
 }
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 37541dee7d9..883b972872f 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -122,20 +122,21 @@ impl<'tcx> CastCheck<'tcx> {
             CastError::NeedViaInt |
             CastError::NeedViaUsize => {
                 fcx.type_error_message(self.span, |actual| {
-                    format!("illegal cast; cast through {} first: `{}` as `{}`",
-                            match e {
-                                CastError::NeedViaPtr => "a raw pointer",
-                                CastError::NeedViaInt => "an integer",
-                                CastError::NeedViaUsize => "a usize",
-                                _ => unreachable!()
-                            },
+                    format!("casting `{}` as `{}` is invalid",
                             actual,
                             fcx.infcx().ty_to_string(self.cast_ty))
-                }, self.expr_ty, None)
+                }, self.expr_ty, None);
+                fcx.ccx.tcx.sess.fileline_help(self.span,
+                    &format!("cast through {} first", match e {
+                        CastError::NeedViaPtr => "a raw pointer",
+                        CastError::NeedViaInt => "an integer",
+                        CastError::NeedViaUsize => "a usize",
+                        _ => unreachable!()
+                }));
             }
             CastError::CastToBool => {
-                span_err!(fcx.tcx().sess, self.span, E0054,
-                          "cannot cast as `bool`, compare with zero instead");
+                span_err!(fcx.tcx().sess, self.span, E0054, "cannot cast as `bool`");
+                fcx.ccx.tcx.sess.fileline_help(self.span, "compare with zero instead");
             }
             CastError::CastToChar => {
                 fcx.type_error_message(self.span, |actual| {
@@ -151,17 +152,18 @@ impl<'tcx> CastCheck<'tcx> {
             }
             CastError::IllegalCast => {
                 fcx.type_error_message(self.span, |actual| {
-                    format!("illegal cast: `{}` as `{}`",
+                    format!("casting `{}` as `{}` is invalid",
                             actual,
                             fcx.infcx().ty_to_string(self.cast_ty))
                 }, self.expr_ty, None);
             }
             CastError::DifferingKinds => {
                 fcx.type_error_message(self.span, |actual| {
-                    format!("illegal cast: `{}` as `{}`; vtable kinds may not match",
+                    format!("casting `{}` as `{}` is invalid",
                             actual,
                             fcx.infcx().ty_to_string(self.cast_ty))
                 }, self.expr_ty, None);
+                fcx.ccx.tcx.sess.fileline_note(self.span, "vtable kinds may not match");
             }
         }
     }
@@ -285,7 +287,7 @@ impl<'tcx> CastCheck<'tcx> {
             return Ok(CastKind::PtrPtrCast);
         }
 
-        // sized -> unsized? report illegal cast (don't complain about vtable kinds)
+        // sized -> unsized? report invalid cast (don't complain about vtable kinds)
         if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
             return Err(CastError::IllegalCast);
         }
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 7926394ebb5..6d8b757d167 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -16,7 +16,6 @@ use middle::subst::{self, Subst, Substs, VecPerParamSpace};
 
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::parse::token;
 
 use super::assoc;
 
@@ -85,7 +84,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
         span_err!(tcx.sess, impl_m_span, E0049,
             "method `{}` has {} type parameter{} \
              but its trait declaration has {} type parameter{}",
-            token::get_name(trait_m.name),
+            trait_m.name,
             num_impl_m_type_params,
             if num_impl_m_type_params == 1 {""} else {"s"},
             num_trait_m_type_params,
@@ -97,7 +96,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
         span_err!(tcx.sess, impl_m_span, E0050,
             "method `{}` has {} parameter{} \
              but the declaration in trait `{}` has {}",
-            token::get_name(trait_m.name),
+            trait_m.name,
             impl_m.fty.sig.0.inputs.len(),
             if impl_m.fty.sig.0.inputs.len() == 1 {""} else {"s"},
             tcx.item_path_str(trait_m.def_id),
@@ -337,7 +336,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                    trait_fty);
             span_err!(tcx.sess, impl_m_span, E0053,
                       "method `{}` has an incompatible type for trait: {}",
-                      token::get_name(trait_m.name),
+                      trait_m.name,
                       terr);
             return;
         }
@@ -401,7 +400,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
             span_err!(tcx.sess, span, E0195,
                 "lifetime parameters or bounds on method `{}` do \
                          not match the trait declaration",
-                         token::get_name(impl_m.name));
+                         impl_m.name);
             return false;
         }
 
@@ -484,7 +483,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
             span_err!(tcx.sess, impl_c_span, E0326,
                       "implemented const `{}` has an incompatible type for \
                       trait: {}",
-                      token::get_name(trait_c.name),
+                      trait_c.name,
                       terr);
             return;
         }
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 38207354792..24e67860998 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -14,6 +14,7 @@ use middle::infer;
 use middle::region;
 use middle::subst::{self, Subst};
 use middle::ty::{self, Ty};
+use util::nodemap::FnvHashSet;
 
 use syntax::ast;
 use syntax::codemap::{self, Span};
@@ -258,17 +259,20 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
     debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
            typ, scope);
 
-    // types that have been traversed so far by `traverse_type_if_unseen`
-    let mut breadcrumbs: Vec<Ty<'tcx>> = Vec::new();
+    let parent_scope = rcx.tcx().region_maps.opt_encl_scope(scope).unwrap_or_else(|| {
+        rcx.tcx().sess.span_bug(
+            span, &format!("no enclosing scope found for scope: {:?}", scope))
+    });
 
     let result = iterate_over_potentially_unsafe_regions_in_type(
-        rcx,
-        &mut breadcrumbs,
+        &mut DropckContext {
+            rcx: rcx,
+            span: span,
+            parent_scope: parent_scope,
+            breadcrumbs: FnvHashSet()
+        },
         TypeContext::Root,
         typ,
-        span,
-        scope,
-        0,
         0);
     match result {
         Ok(()) => {}
@@ -311,6 +315,7 @@ enum Error<'tcx> {
     Overflow(TypeContext, ty::Ty<'tcx>),
 }
 
+#[derive(Copy, Clone)]
 enum TypeContext {
     Root,
     EnumVariant {
@@ -324,269 +329,198 @@ enum TypeContext {
     }
 }
 
-// The `depth` counts the number of calls to this function;
-// the `xref_depth` counts the subset of such calls that go
-// across a `Box<T>` or `PhantomData<T>`.
-fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
-    rcx: &mut Rcx<'a, 'tcx>,
-    breadcrumbs: &mut Vec<Ty<'tcx>>,
-    context: TypeContext,
-    ty_root: ty::Ty<'tcx>,
+struct DropckContext<'a, 'b: 'a, 'tcx: 'b> {
+    rcx: &'a mut Rcx<'b, 'tcx>,
+    /// types that have already been traversed
+    breadcrumbs: FnvHashSet<Ty<'tcx>>,
+    /// span for error reporting
     span: Span,
-    scope: region::CodeExtent,
-    depth: usize,
-    xref_depth: usize) -> Result<(), Error<'tcx>>
+    /// the scope reachable dtorck types must outlive
+    parent_scope: region::CodeExtent
+}
+
+// `context` is used for reporting overflow errors
+fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
+    cx: &mut DropckContext<'a, 'b, 'tcx>,
+    context: TypeContext,
+    ty: Ty<'tcx>,
+    depth: usize) -> Result<(), Error<'tcx>>
 {
+    let tcx = cx.rcx.tcx();
     // Issue #22443: Watch out for overflow. While we are careful to
     // handle regular types properly, non-regular ones cause problems.
-    let recursion_limit = rcx.tcx().sess.recursion_limit.get();
-    if xref_depth >= recursion_limit {
-        return Err(Error::Overflow(context, ty_root))
+    let recursion_limit = tcx.sess.recursion_limit.get();
+    if depth / 4 >= recursion_limit {
+        // This can get into rather deep recursion, especially in the
+        // presence of things like Vec<T> -> Unique<T> -> PhantomData<T> -> T.
+        // use a higher recursion limit to avoid errors.
+        return Err(Error::Overflow(context, ty))
     }
 
-    let origin = || infer::SubregionOrigin::SafeDestructor(span);
-    let mut walker = ty_root.walk();
-    let opt_phantom_data_def_id = rcx.tcx().lang_items.phantom_data();
+    let opt_phantom_data_def_id = tcx.lang_items.phantom_data();
 
-    let destructor_for_type = rcx.tcx().destructor_for_type.borrow();
+    if !cx.breadcrumbs.insert(ty) {
+        debug!("iterate_over_potentially_unsafe_regions_in_type \
+               {}ty: {} scope: {:?} - cached",
+               (0..depth).map(|_| ' ').collect::<String>(),
+               ty, cx.parent_scope);
+        return Ok(()); // we already visited this type
+    }
+    debug!("iterate_over_potentially_unsafe_regions_in_type \
+           {}ty: {} scope: {:?}",
+           (0..depth).map(|_| ' ').collect::<String>(),
+           ty, cx.parent_scope);
+
+    // If `typ` has a destructor, then we must ensure that all
+    // borrowed data reachable via `typ` must outlive the parent
+    // of `scope`. This is handled below.
+    //
+    // However, there is an important special case: by
+    // parametricity, any generic type parameters have *no* trait
+    // bounds in the Drop impl can not be used in any way (apart
+    // from being dropped), and thus we can treat data borrowed
+    // via such type parameters remains unreachable.
+    //
+    // For example, consider `impl<T> Drop for Vec<T> { ... }`,
+    // which does have to be able to drop instances of `T`, but
+    // otherwise cannot read data from `T`.
+    //
+    // Of course, for the type expression passed in for any such
+    // unbounded type parameter `T`, we must resume the recursive
+    // analysis on `T` (since it would be ignored by
+    // type_must_outlive).
+    //
+    // FIXME (pnkfelix): Long term, we could be smart and actually
+    // feed which generic parameters can be ignored *into* `fn
+    // type_must_outlive` (or some generalization thereof). But
+    // for the short term, it probably covers most cases of
+    // interest to just special case Drop impls where: (1.) there
+    // are no generic lifetime parameters and (2.)  *all* generic
+    // type parameters are unbounded.  If both conditions hold, we
+    // simply skip the `type_must_outlive` call entirely (but
+    // resume the recursive checking of the type-substructure).
+    if has_dtor_of_interest(tcx, ty, cx.span) {
+        debug!("iterate_over_potentially_unsafe_regions_in_type \
+                {}ty: {} - is a dtorck type!",
+               (0..depth).map(|_| ' ').collect::<String>(),
+               ty);
 
-    let xref_depth_orig = xref_depth;
+        regionck::type_must_outlive(cx.rcx,
+                                    infer::SubregionOrigin::SafeDestructor(cx.span),
+                                    ty,
+                                    ty::ReScope(cx.parent_scope));
 
-    while let Some(typ) = walker.next() {
-        // Avoid recursing forever.
-        if breadcrumbs.contains(&typ) {
-            continue;
-        }
-        breadcrumbs.push(typ);
-
-        // If we encounter `PhantomData<T>`, then we should replace it
-        // with `T`, the type it represents as owned by the
-        // surrounding context, before doing further analysis.
-        let (typ, xref_depth) = match typ.sty {
-            ty::TyStruct(struct_did, substs) => {
-                if opt_phantom_data_def_id == Some(struct_did) {
-                    let item_type = rcx.tcx().lookup_item_type(struct_did);
-                    let tp_def = item_type.generics.types
-                        .opt_get(subst::TypeSpace, 0).unwrap();
-                    let new_typ = substs.type_for_def(tp_def);
-                    debug!("replacing phantom {:?} with {:?}",
-                           typ, new_typ);
-                    (new_typ, xref_depth_orig + 1)
-                } else {
-                    (typ, xref_depth_orig)
-                }
-            }
-
-            // Note: When TyBox is removed from compiler, the
-            // definition of `Box<T>` must carry a PhantomData that
-            // puts us into the previous case.
-            ty::TyBox(new_typ) => {
-                debug!("replacing TyBox {:?} with {:?}",
-                       typ, new_typ);
-                (new_typ, xref_depth_orig + 1)
-            }
+        return Ok(());
+    }
 
-            _ => {
-                (typ, xref_depth_orig)
-            }
-        };
-
-        let dtor_kind = match typ.sty {
-            ty::TyEnum(def_id, _) |
-            ty::TyStruct(def_id, _) => {
-                match destructor_for_type.get(&def_id) {
-                    Some(def_id) => DtorKind::KnownDropMethod(*def_id),
-                    None => DtorKind::PureRecur,
-                }
-            }
-            ty::TyTrait(ref ty_trait) => {
-                DtorKind::Unknown(ty_trait.bounds.clone())
-            }
-            _ => DtorKind::PureRecur,
-        };
+    debug!("iterate_over_potentially_unsafe_regions_in_type \
+           {}ty: {} scope: {:?} - checking interior",
+           (0..depth).map(|_| ' ').collect::<String>(),
+           ty, cx.parent_scope);
+
+    // We still need to ensure all referenced data is safe.
+    match ty.sty {
+        ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) |
+        ty::TyFloat(_) | ty::TyStr => {
+            // primitive - definitely safe
+            Ok(())
+        }
 
-        debug!("iterate_over_potentially_unsafe_regions_in_type \
-                {}typ: {} scope: {:?} xref: {}",
-               (0..depth).map(|_| ' ').collect::<String>(),
-               typ, scope, xref_depth);
+        ty::TyBox(ity) | ty::TyArray(ity, _) | ty::TySlice(ity) => {
+            // single-element containers, behave like their element
+            iterate_over_potentially_unsafe_regions_in_type(
+                cx, context, ity, depth+1)
+        }
 
-        // If `typ` has a destructor, then we must ensure that all
-        // borrowed data reachable via `typ` must outlive the parent
-        // of `scope`. This is handled below.
-        //
-        // However, there is an important special case: by
-        // parametricity, any generic type parameters have *no* trait
-        // bounds in the Drop impl can not be used in any way (apart
-        // from being dropped), and thus we can treat data borrowed
-        // via such type parameters remains unreachable.
-        //
-        // For example, consider `impl<T> Drop for Vec<T> { ... }`,
-        // which does have to be able to drop instances of `T`, but
-        // otherwise cannot read data from `T`.
-        //
-        // Of course, for the type expression passed in for any such
-        // unbounded type parameter `T`, we must resume the recursive
-        // analysis on `T` (since it would be ignored by
-        // type_must_outlive).
-        //
-        // FIXME (pnkfelix): Long term, we could be smart and actually
-        // feed which generic parameters can be ignored *into* `fn
-        // type_must_outlive` (or some generalization thereof). But
-        // for the short term, it probably covers most cases of
-        // interest to just special case Drop impls where: (1.) there
-        // are no generic lifetime parameters and (2.)  *all* generic
-        // type parameters are unbounded.  If both conditions hold, we
-        // simply skip the `type_must_outlive` call entirely (but
-        // resume the recursive checking of the type-substructure).
-
-        if has_dtor_of_interest(rcx.tcx(), dtor_kind, typ, span) {
-            // If `typ` has a destructor, then we must ensure that all
-            // borrowed data reachable via `typ` must outlive the
-            // parent of `scope`. (It does not suffice for it to
-            // outlive `scope` because that could imply that the
-            // borrowed data is torn down in between the end of
-            // `scope` and when the destructor itself actually runs.)
-
-            let parent_region =
-                match rcx.tcx().region_maps.opt_encl_scope(scope) {
-                    Some(parent_scope) => ty::ReScope(parent_scope),
-                    None => rcx.tcx().sess.span_bug(
-                        span, &format!("no enclosing scope found for scope: {:?}",
-                                       scope)),
-                };
-
-            regionck::type_must_outlive(rcx, origin(), typ, parent_region);
-
-        } else {
-            // Okay, `typ` itself is itself not reachable by a
-            // destructor; but it may contain substructure that has a
-            // destructor.
-
-            match typ.sty {
-                ty::TyStruct(struct_did, substs) => {
-                    debug!("typ: {:?} is struct; traverse structure and not type-expression",
-                           typ);
-                    // Don't recurse; we extract type's substructure,
-                    // so do not process subparts of type expression.
-                    walker.skip_current_subtree();
-
-                    let fields =
-                        rcx.tcx().lookup_struct_fields(struct_did);
-                    for field in &fields {
-                        let field_type = rcx.tcx().lookup_field_type(struct_did,
-                                                                     field.id,
-                                                                     substs);
-                        try!(iterate_over_potentially_unsafe_regions_in_type(
-                            rcx,
-                            breadcrumbs,
-                            TypeContext::Struct {
-                                def_id: struct_did,
-                                field: field.name,
-                            },
-                            field_type,
-                            span,
-                            scope,
-                            depth+1,
-                            xref_depth))
-                    }
-                }
+        ty::TyStruct(did, substs) if Some(did) == opt_phantom_data_def_id => {
+            // PhantomData<T> - behaves identically to T
+            let ity = *substs.types.get(subst::TypeSpace, 0);
+            iterate_over_potentially_unsafe_regions_in_type(
+                cx, context, ity, depth+1)
+        }
 
-                ty::TyEnum(enum_did, substs) => {
-                    debug!("typ: {:?} is enum; traverse structure and not type-expression",
-                           typ);
-                    // Don't recurse; we extract type's substructure,
-                    // so do not process subparts of type expression.
-                    walker.skip_current_subtree();
-
-                    let all_variant_info =
-                        rcx.tcx().substd_enum_variants(enum_did, substs);
-                    for variant_info in &all_variant_info {
-                        for (i, arg_type) in variant_info.args.iter().enumerate() {
-                            try!(iterate_over_potentially_unsafe_regions_in_type(
-                                rcx,
-                                breadcrumbs,
-                                TypeContext::EnumVariant {
-                                    def_id: enum_did,
-                                    variant: variant_info.name,
-                                    arg_index: i,
-                                },
-                                *arg_type,
-                                span,
-                                scope,
-                                depth+1,
-                                xref_depth));
-                        }
-                    }
-                }
+        ty::TyStruct(did, substs) => {
+            let fields = tcx.lookup_struct_fields(did);
+            for field in &fields {
+                let fty = tcx.lookup_field_type(did, field.id, substs);
+                let fty = cx.rcx.fcx.resolve_type_vars_if_possible(
+                    cx.rcx.fcx.normalize_associated_types_in(cx.span, &fty));
+                try!(iterate_over_potentially_unsafe_regions_in_type(
+                    cx,
+                    TypeContext::Struct {
+                        def_id: did,
+                        field: field.name,
+                    },
+                    fty,
+                    depth+1))
+            }
+            Ok(())
+        }
 
-                ty::TyRef(..) | ty::TyRawPtr(_) | ty::TyBareFn(..) => {
-                    // Don't recurse, since references, pointers,
-                    // and bare functions don't own instances
-                    // of the types appearing within them.
-                    walker.skip_current_subtree();
+        ty::TyEnum(did, substs) => {
+            let all_variant_info = tcx.substd_enum_variants(did, substs);
+            for variant_info in &all_variant_info {
+                for (i, fty) in variant_info.args.iter().enumerate() {
+                    let fty = cx.rcx.fcx.resolve_type_vars_if_possible(
+                        cx.rcx.fcx.normalize_associated_types_in(cx.span, &fty));
+                    try!(iterate_over_potentially_unsafe_regions_in_type(
+                        cx,
+                        TypeContext::EnumVariant {
+                            def_id: did,
+                            variant: variant_info.name,
+                            arg_index: i,
+                        },
+                        fty,
+                        depth+1));
                 }
-                _ => {}
-            };
+            }
+            Ok(())
+        }
 
-            // You might be tempted to pop breadcrumbs here after
-            // processing type's internals above, but then you hit
-            // exponential time blowup e.g. on
-            // compile-fail/huge-struct.rs. Instead, we do not remove
-            // anything from the breadcrumbs vector during any particular
-            // traversal, and instead clear it after the whole traversal
-            // is done.
+        ty::TyTuple(ref tys) |
+        ty::TyClosure(_, box ty::ClosureSubsts { upvar_tys: ref tys, .. }) => {
+            for ty in tys {
+                try!(iterate_over_potentially_unsafe_regions_in_type(
+                    cx, context, ty, depth+1))
+            }
+            Ok(())
         }
-    }
 
-    return Ok(());
-}
+        ty::TyRawPtr(..) | ty::TyRef(..) | ty::TyParam(..) => {
+            // these always come with a witness of liveness (references
+            // explicitly, pointers implicitly, parameters by the
+            // caller).
+            Ok(())
+        }
 
-enum DtorKind<'tcx> {
-    // Type has an associated drop method with this def id
-    KnownDropMethod(ast::DefId),
+        ty::TyBareFn(..) => {
+            // FIXME(#26656): this type is always destruction-safe, but
+            // it implicitly witnesses Self: Fn, which can be false.
+            Ok(())
+        }
 
-    // Type has no destructor (or its dtor is known to be pure
-    // with respect to lifetimes), though its *substructure*
-    // may carry a destructor.
-    PureRecur,
+        ty::TyInfer(..) | ty::TyError => {
+            tcx.sess.delay_span_bug(cx.span, "unresolved type in regionck");
+            Ok(())
+        }
 
-    // Type may have impure destructor that is unknown;
-    // e.g. `Box<Trait+'a>`
-    Unknown(ty::ExistentialBounds<'tcx>),
+        // these are always dtorck
+        ty::TyTrait(..) | ty::TyProjection(_) => unreachable!(),
+    }
 }
 
 fn has_dtor_of_interest<'tcx>(tcx: &ty::ctxt<'tcx>,
-                              dtor_kind: DtorKind,
-                              typ: ty::Ty<'tcx>,
+                              ty: ty::Ty<'tcx>,
                               span: Span) -> bool {
-    let has_dtor_of_interest: bool;
-
-    match dtor_kind {
-        DtorKind::PureRecur => {
-            has_dtor_of_interest = false;
-            debug!("typ: {:?} has no dtor, and thus is uninteresting",
-                   typ);
-        }
-        DtorKind::Unknown(bounds) => {
-            match bounds.region_bound {
-                ty::ReStatic => {
-                    debug!("trait: {:?} has 'static bound, and thus is uninteresting",
-                           typ);
-                    has_dtor_of_interest = false;
-                }
-                ty::ReEmpty => {
-                    debug!("trait: {:?} has empty region bound, and thus is uninteresting",
-                           typ);
-                    has_dtor_of_interest = false;
+    match ty.sty {
+        ty::TyEnum(def_id, _) | ty::TyStruct(def_id, _) => {
+            let dtor_method_did = match tcx.destructor_for_type.borrow().get(&def_id) {
+                Some(def_id) => *def_id,
+                None => {
+                    debug!("ty: {:?} has no dtor, and thus isn't a dropck type", ty);
+                    return false;
                 }
-                r => {
-                    debug!("trait: {:?} has non-static bound: {:?}; assumed interesting",
-                           typ, r);
-                    has_dtor_of_interest = true;
-                }
-            }
-        }
-        DtorKind::KnownDropMethod(dtor_method_did) => {
+            };
             let impl_did = tcx.impl_of_method(dtor_method_did)
                 .unwrap_or_else(|| {
                     tcx.sess.span_bug(
@@ -638,8 +572,8 @@ fn has_dtor_of_interest<'tcx>(tcx: &ty::ctxt<'tcx>,
 
                     if result {
                         has_pred_of_interest = true;
-                        debug!("typ: {:?} has interesting dtor due to generic preds, e.g. {:?}",
-                               typ, pred);
+                        debug!("ty: {:?} has interesting dtor due to generic preds, e.g. {:?}",
+                               ty, pred);
                         break 'items;
                     }
                 }
@@ -658,22 +592,25 @@ fn has_dtor_of_interest<'tcx>(tcx: &ty::ctxt<'tcx>,
             let has_region_param_of_interest =
                 dtor_generics.has_region_params(subst::TypeSpace);
 
-            has_dtor_of_interest =
+            let has_dtor_of_interest =
                 has_region_param_of_interest ||
                 has_pred_of_interest;
 
             if has_dtor_of_interest {
-                debug!("typ: {:?} has interesting dtor, due to \
+                debug!("ty: {:?} has interesting dtor, due to \
                         region params: {} or pred: {}",
-                       typ,
+                       ty,
                        has_region_param_of_interest,
                        has_pred_of_interest);
             } else {
-                debug!("typ: {:?} has dtor, but it is uninteresting",
-                       typ);
+                debug!("ty: {:?} has dtor, but it is uninteresting", ty);
             }
+            has_dtor_of_interest
         }
+        ty::TyTrait(..) | ty::TyProjection(..) => {
+            debug!("ty: {:?} isn't known, and therefore is a dropck type", ty);
+            true
+        },
+        _ => false
     }
-
-    return has_dtor_of_interest;
 }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index e3f55cca9ee..fd5d8d8d196 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -334,19 +334,14 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, expr_id));
     let def_id = pick.item.def_id();
     let mut lp = LastMod(AllPublic);
-    let container_def_id = pick.item.container().id();
-    let provenance = match pick.kind {
-        probe::InherentImplPick => {
-            if pick.item.vis() != ast::Public {
-                lp = LastMod(DependsOn(def_id));
-            }
-            def::FromImpl(container_def_id)
+    if let probe::InherentImplPick = pick.kind {
+        if pick.item.vis() != ast::Public {
+            lp = LastMod(DependsOn(def_id));
         }
-        _ => def::FromTrait(container_def_id)
-    };
+    }
     let def_result = match pick.item {
-        ty::ImplOrTraitItem::MethodTraitItem(..) => def::DefMethod(def_id, provenance),
-        ty::ImplOrTraitItem::ConstTraitItem(..) => def::DefAssociatedConst(def_id, provenance),
+        ty::ImplOrTraitItem::MethodTraitItem(..) => def::DefMethod(def_id),
+        ty::ImplOrTraitItem::ConstTraitItem(..) => def::DefAssociatedConst(def_id),
         ty::ImplOrTraitItem::TypeTraitItem(..) => {
             fcx.tcx().sess.span_bug(span, "resolve_ufcs: probe picked associated type");
         }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 0c60cdc4ca2..6851fb46670 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -119,7 +119,7 @@ use syntax::ast_util::{self, local_def};
 use syntax::codemap::{self, Span};
 use syntax::feature_gate::emit_feature_err;
 use syntax::owned_slice::OwnedSlice;
-use syntax::parse::token;
+use syntax::parse::token::{self, InternedString};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::visit::{self, Visitor};
@@ -505,7 +505,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
                                                traits::VariableType(p.id));
 
                 debug!("Pattern binding {} is assigned to {} with type {:?}",
-                       token::get_ident(path1.node),
+                       path1.node,
                        self.fcx.infcx().ty_to_string(
                            self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
                        var_ty);
@@ -662,7 +662,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
       }
       ast::ItemFn(..) => {} // entirely within check_item_body
       ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
-          debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
+          debug!("ItemImpl {} with id {}", it.ident, it.id);
           match ccx.tcx.impl_trait_ref(local_def(it.id)) {
               Some(impl_trait_ref) => {
                 check_impl_items_against_trait(ccx,
@@ -718,7 +718,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
         check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
       }
       ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
-        debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
+        debug!("ItemImpl {} with id {}", it.ident, it.id);
 
         let impl_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
 
@@ -796,14 +796,14 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         Position::ArgumentNamed(s) if s == "Self" => (),
                         // So is `{A}` if A is a type parameter
                         Position::ArgumentNamed(s) => match types.iter().find(|t| {
-                            t.ident.as_str() == s
+                            t.ident.name == s
                         }) {
                             Some(_) => (),
                             None => {
                                 span_err!(ccx.tcx.sess, attr.span, E0230,
                                                  "there is no type parameter \
                                                           {} on trait {}",
-                                                           s, item.ident.as_str());
+                                                           s, item.ident);
                             }
                         },
                         // `{:1}` and `{}` are not to be used
@@ -865,7 +865,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                 // This is checked by resolve
                 tcx.sess.span_bug(impl_item.span,
                                   &format!("impl-item `{}` is not a member of `{:?}`",
-                                           token::get_name(ty_impl_item.name()),
+                                           ty_impl_item.name(),
                                            impl_trait_ref));
             });
         match impl_item.node {
@@ -886,7 +886,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                     span_err!(tcx.sess, impl_item.span, E0323,
                               "item `{}` is an associated const, \
                               which doesn't match its trait `{:?}`",
-                              token::get_name(impl_const.name),
+                              impl_const.name,
                               impl_trait_ref)
                 }
             }
@@ -909,7 +909,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                     span_err!(tcx.sess, impl_item.span, E0324,
                               "item `{}` is an associated method, \
                               which doesn't match its trait `{:?}`",
-                              token::get_name(impl_method.name),
+                              impl_method.name,
                               impl_trait_ref)
                 }
             }
@@ -927,7 +927,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                     span_err!(tcx.sess, impl_item.span, E0325,
                               "item `{}` is an associated type, \
                               which doesn't match its trait `{:?}`",
-                              token::get_name(impl_type.name),
+                              impl_type.name,
                               impl_trait_ref)
                 }
             }
@@ -1009,7 +1009,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         span_err!(tcx.sess, impl_span, E0046,
             "not all trait items implemented, missing: `{}`",
             missing_items.iter()
-                  .map(<ast::Name>::as_str)
+                  .map(|name| name.to_string())
                   .collect::<Vec<_>>().join("`, `"))
     }
 
@@ -1018,9 +1018,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         span_err!(tcx.sess, invalidator.span, E0399,
                   "the following trait items need to be reimplemented \
                    as `{}` was overridden: `{}`",
-                  invalidator.ident.as_str(),
+                  invalidator.ident,
                   invalidated_items.iter()
-                                   .map(<ast::Name>::as_str)
+                                   .map(|name| name.to_string())
                                    .collect::<Vec<_>>().join("`, `"))
     }
 }
@@ -2901,7 +2901,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                 field.span,
                 |actual| {
                     format!("attempted to take value of method `{}` on type \
-                            `{}`", token::get_ident(field.node), actual)
+                            `{}`", field.node, actual)
                 },
                 expr_t, None);
 
@@ -2915,7 +2915,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                     format!("attempted access of field `{}` on \
                             type `{}`, but no field with that \
                             name was found",
-                            token::get_ident(field.node),
+                            field.node,
                             actual)
                 },
                 expr_t, None);
@@ -2931,9 +2931,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
     fn suggest_field_names<'tcx>(id : DefId,
                                  field : &ast::SpannedIdent,
                                  tcx : &ty::ctxt<'tcx>,
-                                 skip : Vec<&str>) {
-        let ident = token::get_ident(field.node);
-        let name = &ident;
+                                 skip : Vec<InternedString>) {
+        let name = field.node.name.as_str();
         // only find fits with at least one matching letter
         let mut best_dist = name.len();
         let fields = tcx.lookup_struct_fields(id);
@@ -2941,14 +2940,14 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         for elem in &fields {
             let n = elem.name.as_str();
             // ignore already set fields
-            if skip.iter().any(|&x| x == n) {
+            if skip.iter().any(|x| *x == n) {
                 continue;
             }
             // ignore private fields from non-local crates
             if id.krate != ast::LOCAL_CRATE && elem.vis != Visibility::Public {
                 continue;
             }
-            let dist = lev_distance(n, name);
+            let dist = lev_distance(&n, &name);
             if dist < best_dist {
                 best = Some(n);
                 best_dist = dist;
@@ -3061,12 +3060,12 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                                                             class_id);
                                 format!("struct variant `{}::{}` has no field named `{}`",
                                         actual, variant_type.name.as_str(),
-                                        token::get_ident(field.ident.node))
+                                        field.ident.node)
                             }
                             None => {
                                 format!("structure `{}` has no field named `{}`",
                                         actual,
-                                        token::get_ident(field.ident.node))
+                                        field.ident.node)
                             }
                         },
                         struct_ty,
@@ -3083,7 +3082,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                 Some((_, true)) => {
                     span_err!(fcx.tcx().sess, field.ident.span, E0062,
                         "field `{}` specified more than once",
-                        token::get_ident(field.ident.node));
+                        field.ident.node);
                     error_happened = true;
                 }
                 Some((field_id, false)) => {
@@ -3117,7 +3116,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                     let (_, seen) = *class_field_map.get(&name).unwrap();
                     if !seen {
                         missing_fields.push(
-                            format!("`{}`", &token::get_name(name)))
+                            format!("`{}`", name))
                     }
                 }
 
@@ -3469,7 +3468,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         let tcx = fcx.tcx();
         if !tcx.expr_is_lval(&**lhs) {
             span_err!(tcx.sess, expr.span, E0070,
-                "illegal left-hand side expression");
+                "invalid left-hand side expression");
         }
 
         let lhs_ty = fcx.expr_ty(&**lhs);
@@ -4274,10 +4273,8 @@ pub fn check_representable(tcx: &ty::ctxt,
     // caught by case 1.
     match rty.is_representable(tcx, sp) {
       ty::SelfRecursive => {
-        span_err!(tcx.sess, sp, E0072,
-            "illegal recursive {} type; \
-             wrap the inner value in a box to make it representable",
-            designation);
+        span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation);
+        tcx.sess.fileline_help(sp, "wrap the inner value in a box to make it representable");
         return false
       }
       ty::Representable | ty::ContainsRecursive => (),
@@ -4450,9 +4447,9 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
              ty::GenericPredicates::empty())
         }
-        def::DefFn(id, _) | def::DefMethod(id, _) |
+        def::DefFn(id, _) | def::DefMethod(id) |
         def::DefStatic(id, _) | def::DefVariant(_, id, _) |
-        def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
+        def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
             (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
         }
         def::DefTrait(_) |
@@ -4558,7 +4555,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
     assert!(!segments.is_empty());
 
-    let mut ufcs_method = None;
+    let mut ufcs_associated = None;
     let mut segment_spaces: Vec<_>;
     match def {
         // Case 1 and 1b. Reference to a *type* or *enum variant*.
@@ -4585,12 +4582,13 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
 
         // Case 3. Reference to a method.
-        def::DefMethod(_, provenance) => {
-            match provenance {
-                def::FromTrait(trait_did) => {
+        def::DefMethod(def_id) => {
+            let container = fcx.tcx().impl_or_trait_item(def_id).container();
+            match container {
+                ty::TraitContainer(trait_did) => {
                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
                 }
-                def::FromImpl(_) => {}
+                ty::ImplContainer(_) => {}
             }
 
             if segments.len() >= 2 {
@@ -4601,16 +4599,17 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 // `<T>::method` will end up here, and so can `T::method`.
                 let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
                 segment_spaces = vec![Some(subst::FnSpace)];
-                ufcs_method = Some((provenance, self_ty));
+                ufcs_associated = Some((container, self_ty));
             }
         }
 
-        def::DefAssociatedConst(_, provenance) => {
-            match provenance {
-                def::FromTrait(trait_did) => {
+        def::DefAssociatedConst(def_id) => {
+            let container = fcx.tcx().impl_or_trait_item(def_id).container();
+            match container {
+                ty::TraitContainer(trait_did) => {
                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
                 }
-                def::FromImpl(_) => {}
+                ty::ImplContainer(_) => {}
             }
 
             if segments.len() >= 2 {
@@ -4618,7 +4617,10 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 segment_spaces.push(Some(subst::TypeSpace));
                 segment_spaces.push(None);
             } else {
+                // `<T>::CONST` will end up here, and so can `T::CONST`.
+                let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
                 segment_spaces = vec![None];
+                ufcs_associated = Some((container, self_ty));
             }
         }
 
@@ -4640,7 +4642,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
     // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
     // type parameters are not mandatory.
-    let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
+    let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
 
     debug!("segment_spaces={:?}", segment_spaces);
 
@@ -4710,7 +4712,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
 
 
-    if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
+    if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
         // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
         // is inherent, there is no `Self` parameter, instead, the impl needs
         // type parameters, which we can infer by unifying the provided `Self`
@@ -5059,7 +5061,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         if !*b {
             span_err!(ccx.tcx.sess, span, E0091,
                 "type parameter `{}` is unused",
-                token::get_ident(tps[i].ident));
+                tps[i].ident);
         }
     }
 }
@@ -5073,7 +5075,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
     }
 
     let tcx = ccx.tcx;
-    let name = token::get_ident(it.ident);
+    let name = it.ident.name.as_str();
     let (n_tps, inputs, output) = if name.starts_with("atomic_") {
         let split : Vec<&str> = name.split('_').collect();
         assert!(split.len() >= 2, "Atomic intrinsic not correct format");
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index c419a986f95..c6d13d3b0a5 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -57,7 +57,7 @@ pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
 
     let tcx = fcx.tcx();
     if !tcx.expr_is_lval(lhs_expr) {
-        span_err!(tcx.sess, lhs_expr.span, E0067, "illegal left-hand side expression");
+        span_err!(tcx.sess, lhs_expr.span, E0067, "invalid left-hand side expression");
     }
 
     fcx.require_expr_have_sized_type(lhs_expr, traits::AssignmentLhsSized);
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index c6f543210ad..aeac38dab90 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -174,7 +174,7 @@ pub fn regionck_ensure_component_tys_wf<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 // INTERNALS
 
 pub struct Rcx<'a, 'tcx: 'a> {
-    fcx: &'a FnCtxt<'a, 'tcx>,
+    pub fcx: &'a FnCtxt<'a, 'tcx>,
 
     region_bound_pairs: Vec<(ty::Region, GenericKind<'tcx>)>,
 
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 6083a2735c5..cfb7dfc54aa 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -23,7 +23,7 @@ use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_util::local_def;
 use syntax::codemap::{DUMMY_SP, Span};
-use syntax::parse::token::{self, special_idents};
+use syntax::parse::token::special_idents;
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -422,7 +422,7 @@ fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>,
         if impl_params.contains(&method_param.name) {
             span_err!(tcx.sess, span, E0194,
                 "type parameter `{}` shadows another type parameter of the same name",
-                          token::get_name(method_param.name));
+                          method_param.name);
         }
     }
 }
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 2b800bd9a44..418d592c962 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -383,14 +383,14 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
                                  "the trait `Copy` may not be \
                                           implemented for this type; field \
                                           `{}` does not implement `Copy`",
-                                         token::get_name(name))
+                                         name)
                 }
                 Err(ty::VariantDoesNotImplementCopy(name)) => {
                        span_err!(tcx.sess, span, E0205,
                                  "the trait `Copy` may not be \
                                           implemented for this type; variant \
                                           `{}` does not implement `Copy`",
-                                         token::get_name(name))
+                                         name)
                 }
                 Err(ty::TypeIsStructural) => {
                        span_err!(tcx.sess, span, E0206,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 00537f66bbc..5b65f780830 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -91,7 +91,6 @@ use syntax::ast;
 use syntax::ast_util::local_def;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::visit;
 
@@ -795,7 +794,7 @@ fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
 
 fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
     let tcx = ccx.tcx;
-    debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
+    debug!("convert: item {} with id {}", it.ident, it.id);
     match it.node {
         // These don't define types.
         ast::ItemExternCrate(_) | ast::ItemUse(_) |
@@ -1086,7 +1085,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                 Some(prev_span) => {
                     span_err!(tcx.sess, f.span, E0124,
                               "field `{}` is already declared",
-                              token::get_name(result.name));
+                              result.name);
                     span_note!(tcx.sess, *prev_span, "previously declared here");
                     true
                 },
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 73ee3bbbe5b..07c1b5e3d20 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -584,7 +584,7 @@ extern "C" {
 ```
 
 Using this declaration, it must be called with at least one argument, so
-simply calling `printf()` is illegal. But the following uses are allowed:
+simply calling `printf()` is invalid. But the following uses are allowed:
 
 ```
 unsafe {
@@ -778,7 +778,7 @@ the pointer the size of the type would need to be unbounded.
 Consider the following erroneous definition of a type for a list of bytes:
 
 ```
-// error, illegal recursive struct type
+// error, invalid recursive struct type
 struct ListNode {
     head: u8,
     tail: Option<ListNode>,
@@ -826,6 +826,63 @@ struct Foo { x: Option<Box<Foo>> }
 Now it's possible to create at least one instance of `Foo`: `Foo { x: None }`.
 "##,
 
+E0074: r##"
+When using the `#[simd]` attribute on a tuple struct, the components of the
+tuple struct must all be of a concrete, nongeneric type so the compiler can
+reason about how to use SIMD with them. This error will occur if the types
+are generic.
+
+```
+#[simd]
+struct Bad<T>(T, T, T); // This will cause an error
+
+#[simd]
+struct Good(u32, u32, u32); // This will not
+```
+"##,
+
+E0075: r##"
+The `#[simd]` attribute can only be applied to non empty tuple structs, because
+it doesn't make sense to try to use SIMD operations when there are no values to
+operate on.
+
+```
+#[simd]
+struct Bad; // This will cause an error
+
+#[simd]
+struct Good(u32); // This will not
+```
+"##,
+
+E0076: r##"
+When using the `#[simd]` attribute to automatically use SIMD operations in tuple
+struct, the types in the struct must all be of the same type, or the compiler
+will trigger this error.
+
+```
+#[simd]
+struct Bad(u16, u32, u32); // This will cause an error
+
+#[simd]
+struct Good(u32, u32, u32); // This will not
+```
+
+"##,
+
+E0077: r##"
+When using the `#[simd]` attribute on a tuple struct, the elements in the tuple
+must be machine types so SIMD operations can be applied to them.
+
+```
+#[simd]
+struct Bad(String); // This will cause an error
+
+#[simd]
+struct Good(u32, u32, u32); // This will not
+```
+"##,
+
 E0081: r##"
 Enum discriminants are used to differentiate enum variants stored in memory.
 This error indicates that the same value was used for two or more variants,
@@ -1227,16 +1284,22 @@ impl Bytes { ... } // error, same as above
 "##,
 
 E0117: r##"
-You got this error because because you tried to implement a foreign
-trait for a foreign type (with maybe a foreign type parameter). Erroneous
-code example:
+This error indicates a violation of one of Rust's orphan rules for trait
+implementations. The rule prohibits any implementation of a foreign trait (a
+trait defined in another crate) where
+
+ - the type that is implementing the trait is foreign
+ - all of the parameters being passed to the trait (if there are any) are also
+   foreign.
+
+Here's one example of this error:
 
 ```
 impl Drop for u32 {}
 ```
 
-The type, trait or the type parameter (or all of them) has to be defined
-in your crate. Example:
+To avoid this kind of error, ensure that at least one local type is referenced
+by the `impl`:
 
 ```
 pub struct Foo; // you define your type in your crate
@@ -1245,14 +1308,6 @@ impl Drop for Foo { // and you can implement the trait on it!
     // code of trait implementation here
 }
 
-trait Bar { // or define your trait in your crate
-    fn get(&self) -> usize;
-}
-
-impl Bar for u32 { // and then you implement it on a foreign type
-    fn get(&self) -> usize { 0 }
-}
-
 impl From<Foo> for i32 { // or you use a type from your crate as
                          // a type parameter
     fn from(i: Foo) -> i32 {
@@ -1260,11 +1315,27 @@ impl From<Foo> for i32 { // or you use a type from your crate as
     }
 }
 ```
+
+Alternatively, define a trait locally and implement that instead:
+
+```
+trait Bar {
+    fn get(&self) -> usize;
+}
+
+impl Bar for u32 {
+    fn get(&self) -> usize { 0 }
+}
+```
+
+For information on the design of the orphan rules, see [RFC 1023].
+
+[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
 "##,
 
 E0119: r##"
 There are conflicting trait implementations for the same type.
-Erroneous code example:
+Example of erroneous code:
 
 ```
 trait MyTrait {
@@ -1285,7 +1356,10 @@ impl MyTrait for Foo { // error: conflicting implementations for trait
 }
 ```
 
-When you write:
+When looking for the implementation for the trait, the compiler finds
+both the `impl<T> MyTrait for T` where T is all types and the `impl
+MyTrait for Foo`. Since a trait cannot be implemented multiple times,
+this is an error. So, when you write:
 
 ```
 impl<T> MyTrait for T {
@@ -1886,6 +1960,71 @@ impl MyTrait for Foo {
 ```
 "##,
 
+E0210: r##"
+This error indicates a violation of one of Rust's orphan rules for trait
+implementations. The rule concerns the use of type parameters in an
+implementation of a foreign trait (a trait defined in another crate), and
+states that type parameters must be "covered" by a local type. To understand
+what this means, it is perhaps easiest to consider a few examples.
+
+If `ForeignTrait` is a trait defined in some external crate `foo`, then the
+following trait `impl` is an error:
+
+```
+extern crate foo;
+use foo::ForeignTrait;
+
+impl<T> ForeignTrait for T { ... } // error
+```
+
+To work around this, it can be covered with a local type, `MyType`:
+
+```
+struct MyType<T>(T);
+impl<T> ForeignTrait for MyType<T> { ... } // Ok
+```
+
+For another example of an error, suppose there's another trait defined in `foo`
+named `ForeignTrait2` that takes two type parameters. Then this `impl` results
+in the same rule violation:
+
+```
+struct MyType2;
+impl<T> ForeignTrait2<T, MyType<T>> for MyType2 { ... } // error
+```
+
+The reason for this is that there are two appearances of type parameter `T` in
+the `impl` header, both as parameters for `ForeignTrait2`. The first appearance
+is uncovered, and so runs afoul of the orphan rule.
+
+Consider one more example:
+
+```
+impl<T> ForeignTrait2<MyType<T>, T> for MyType2 { ... } // Ok
+```
+
+This only differs from the previous `impl` in that the parameters `T` and
+`MyType<T>` for `ForeignTrait2` have been swapped. This example does *not*
+violate the orphan rule; it is permitted.
+
+To see why that last example was allowed, you need to understand the general
+rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`:
+
+```
+impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
+```
+
+where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn`
+are types. One of the types `T0, ..., Tn` must be a local type (this is another
+orphan rule, see the explanation for E0117). Let `i` be the smallest integer
+such that `Ti` is a local type. Then no type parameter can appear in any of the
+`Tj` for `j < i`.
+
+For information on the design of the orphan rules, see [RFC 1023].
+
+[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
+"##,
+
 E0211: r##"
 You used an intrinsic function which doesn't correspond to its
 definition. Erroneous code example:
@@ -2215,6 +2354,23 @@ For more information see the [opt-in builtin traits RFC](https://github.com/rust
 -lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md).
 "##,
 
+E0391: r##"
+This error indicates that some types or traits depend on each other
+and therefore cannot be constructed.
+
+The following example contains a circular dependency between two traits:
+
+```
+trait FirstTrait : SecondTrait {
+
+}
+
+trait SecondTrait : FirstTrait {
+
+}
+```
+"##,
+
 E0392: r##"
 This error indicates that a type or lifetime parameter has been declared
 but not actually used.  Here is an example that demonstrates the error:
@@ -2279,10 +2435,6 @@ https://doc.rust-lang.org/std/marker/struct.PhantomData.html
 
 register_diagnostics! {
     E0068,
-    E0074,
-    E0075,
-    E0076,
-    E0077,
     E0085,
     E0086,
     E0090,
@@ -2315,18 +2467,17 @@ register_diagnostics! {
            // and only one is supported
     E0208,
     E0209, // builtin traits can only be implemented on structs or enums
-    E0210, // type parameter is not constrained by any local type
     E0212, // cannot extract an associated type from a higher-ranked trait bound
     E0213, // associated types are not accepted in this context
     E0214, // parenthesized parameters may only be used with a trait
-    E0215, // angle-bracket notation is not stable with `Fn`
-    E0216, // parenthetical notation is only stable with `Fn`
+//  E0215, // angle-bracket notation is not stable with `Fn`
+//  E0216, // parenthetical notation is only stable with `Fn`
     E0217, // ambiguous associated type, defined in multiple supertraits
     E0218, // no associated type defined
     E0219, // associated type defined in higher-ranked supertrait
     E0221, // ambiguous associated type in bounds
-    //E0222, // Error code E0045 (variadic function must have C calling
-             // convention) duplicate
+//  E0222, // Error code E0045 (variadic function must have C calling
+           // convention) duplicate
     E0224, // at least one non-builtin train is required for an object type
     E0226, // only a single explicit lifetime bound is permitted
     E0227, // ambiguous lifetime bound, explicit lifetime bound required
@@ -2345,7 +2496,7 @@ register_diagnostics! {
     E0241,
     E0242, // internal error looking up a definition
     E0245, // not a trait
-    E0246, // illegal recursive type
+    E0246, // invalid recursive type
     E0247, // found module name used as a type
     E0248, // found value name used as a type
     E0319, // trait impls for defaulted traits allowed just for structs/enums
@@ -2370,7 +2521,6 @@ register_diagnostics! {
            // between structures with the same definition
     E0390, // only a single inherent implementation marked with
            // `#[lang = \"{}\"]` is allowed for the `{}` primitive
-    E0391, // unsupported cyclic reference between types/traits detected
     E0393, // the type parameter `{}` must be explicitly specified in an object
            // type because its default value `{}` references the type `Self`"
     E0399, // trait items need to be implemented because the associated
diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs
index 34b0ae18d4f..815c1ed4fff 100644
--- a/src/librustc_unicode/char.rs
+++ b/src/librustc_unicode/char.rs
@@ -278,7 +278,8 @@ impl char {
     /// In both of these examples, 'ß' takes two bytes to encode.
     ///
     /// ```
-    /// # #![feature(unicode)]
+    /// #![feature(unicode)]
+    ///
     /// let mut b = [0; 2];
     ///
     /// let result = 'ß'.encode_utf8(&mut b);
@@ -289,7 +290,8 @@ impl char {
     /// A buffer that's too small:
     ///
     /// ```
-    /// # #![feature(unicode)]
+    /// #![feature(unicode)]
+    ///
     /// let mut b = [0; 1];
     ///
     /// let result = 'ß'.encode_utf8(&mut b);
@@ -315,7 +317,8 @@ impl char {
     /// In both of these examples, 'ß' takes one `u16` to encode.
     ///
     /// ```
-    /// # #![feature(unicode)]
+    /// #![feature(unicode)]
+    ///
     /// let mut b = [0; 1];
     ///
     /// let result = 'ß'.encode_utf16(&mut b);
@@ -326,7 +329,8 @@ impl char {
     /// A buffer that's too small:
     ///
     /// ```
-    /// # #![feature(unicode)]
+    /// #![feature(unicode)]
+    ///
     /// let mut b = [0; 0];
     ///
     /// let result = 'ß'.encode_utf8(&mut b);
diff --git a/src/librustc_unicode/u_str.rs b/src/librustc_unicode/u_str.rs
index f4c85f18a7e..e329785d271 100644
--- a/src/librustc_unicode/u_str.rs
+++ b/src/librustc_unicode/u_str.rs
@@ -494,7 +494,8 @@ impl<'a> Iterator for Utf16Items<'a> {
 /// # Examples
 ///
 /// ```
-/// # #![feature(unicode)]
+/// #![feature(unicode)]
+///
 /// extern crate rustc_unicode;
 ///
 /// use rustc_unicode::str::Utf16Item::{ScalarValue, LoneSurrogate};
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index e80fd360e04..31cd8ce1b53 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -107,7 +107,7 @@ fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt,
             record_extern_fqn(cx, did, clean::TypeStatic);
             clean::StaticItem(build_static(cx, tcx, did, mtbl))
         }
-        def::DefConst(did) | def::DefAssociatedConst(did, _) => {
+        def::DefConst(did) | def::DefAssociatedConst(did) => {
             record_extern_fqn(cx, did, clean::TypeConst);
             clean::ConstantItem(build_const(cx, tcx, did))
         }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index d4eeaa1de10..11a0e0eaa49 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -745,19 +745,19 @@ impl Lifetime {
 
 impl Clean<Lifetime> for ast::Lifetime {
     fn clean(&self, _: &DocContext) -> Lifetime {
-        Lifetime(token::get_name(self.name).to_string())
+        Lifetime(self.name.to_string())
     }
 }
 
 impl Clean<Lifetime> for ast::LifetimeDef {
     fn clean(&self, _: &DocContext) -> Lifetime {
-        Lifetime(token::get_name(self.lifetime.name).to_string())
+        Lifetime(self.lifetime.name.to_string())
     }
 }
 
 impl Clean<Lifetime> for ty::RegionParameterDef {
     fn clean(&self, _: &DocContext) -> Lifetime {
-        Lifetime(token::get_name(self.name).to_string())
+        Lifetime(self.name.to_string())
     }
 }
 
@@ -766,7 +766,7 @@ impl Clean<Option<Lifetime>> for ty::Region {
         match *self {
             ty::ReStatic => Some(Lifetime::statik()),
             ty::ReLateBound(_, ty::BrNamed(_, name)) =>
-                Some(Lifetime(token::get_name(name).to_string())),
+                Some(Lifetime(name.to_string())),
             ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))),
 
             ty::ReLateBound(..) |
@@ -1695,7 +1695,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
 
             ty::TyProjection(ref data) => data.clean(cx),
 
-            ty::TyParam(ref p) => Generic(token::get_name(p.name).to_string()),
+            ty::TyParam(ref p) => Generic(p.name.to_string()),
 
             ty::TyClosure(..) => Tuple(vec![]), // FIXME(pcwalton)
 
@@ -2048,7 +2048,7 @@ impl Clean<PathSegment> for ast::PathSegment {
 fn path_to_string(p: &ast::Path) -> String {
     let mut s = String::new();
     let mut first = true;
-    for i in p.segments.iter().map(|x| token::get_ident(x.identifier)) {
+    for i in p.segments.iter().map(|x| x.identifier.name.as_str()) {
         if !first || p.global {
             s.push_str("::");
         } else {
@@ -2061,13 +2061,13 @@ fn path_to_string(p: &ast::Path) -> String {
 
 impl Clean<String> for ast::Ident {
     fn clean(&self, _: &DocContext) -> String {
-        token::get_ident(*self).to_string()
+        self.to_string()
     }
 }
 
 impl Clean<String> for ast::Name {
     fn clean(&self, _: &DocContext) -> String {
-        token::get_name(*self).to_string()
+        self.to_string()
     }
 }
 
@@ -2532,14 +2532,14 @@ fn name_from_pat(p: &ast::Pat) -> String {
     match p.node {
         PatWild(PatWildSingle) => "_".to_string(),
         PatWild(PatWildMulti) => "..".to_string(),
-        PatIdent(_, ref p, _) => token::get_ident(p.node).to_string(),
+        PatIdent(_, ref p, _) => p.node.to_string(),
         PatEnum(ref p, _) => path_to_string(p),
         PatQPath(..) => panic!("tried to get argument name from PatQPath, \
                                 which is not allowed in function arguments"),
         PatStruct(ref name, ref fields, etc) => {
             format!("{} {{ {}{} }}", path_to_string(name),
                 fields.iter().map(|&Spanned { node: ref fp, .. }|
-                                  format!("{}: {}", fp.ident.as_str(), name_from_pat(&*fp.pat)))
+                                  format!("{}: {}", fp.ident, name_from_pat(&*fp.pat)))
                              .collect::<Vec<String>>().join(", "),
                 if etc { ", ..." } else { "" }
             )
@@ -2603,7 +2603,7 @@ fn resolve_type(cx: &DocContext,
             ast::TyFloat(ast::TyF64) => return Primitive(F64),
         },
         def::DefSelfTy(..) if path.segments.len() == 1 => {
-            return Generic(token::get_name(special_idents::type_self.name).to_string());
+            return Generic(special_idents::type_self.name.to_string());
         }
         def::DefSelfTy(..) | def::DefTyParam(..) => true,
         _ => false,
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index e375ec3afc2..3facaef7b28 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -75,7 +75,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
                 continue
             },
             token::Shebang(s) => {
-                try!(write!(out, "{}", Escape(s.as_str())));
+                try!(write!(out, "{}", Escape(&s.as_str())));
                 continue
             },
             // If this '&' token is directly adjacent to another token, assume
@@ -141,7 +141,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
 
             // keywords are also included in the identifier set
             token::Ident(ident, _is_mod_sep) => {
-                match &token::get_ident(ident)[..] {
+                match &*ident.name.as_str() {
                     "ref" | "mut" => "kw-2",
 
                     "self" => "self",
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 18f8ce3385f..51dc8c6e477 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -113,8 +113,8 @@ r##"<!DOCTYPE html>
                 <p>
                     Accepted types are: <code>fn</code>, <code>mod</code>,
                     <code>struct</code>, <code>enum</code>,
-                    <code>trait</code>, <code>typedef</code> (or
-                    <code>tdef</code>).
+                    <code>trait</code>, <code>type</code>, <code>macro</code>,
+                    and <code>const</code>.
                 </p>
 
                 <p>
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 1d2cc38b4fc..f1351893915 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -230,6 +230,28 @@
                 }
             }
 
+            function typePassesFilter(filter, type) {
+                // No filter
+                if (filter < 0) return true;
+
+                // Exact match
+                if (filter === type) return true;
+
+                // Match related items
+                var name = itemTypes[type];
+                switch (itemTypes[filter]) {
+                    case "constant":
+                        return (name == "associatedconstant");
+                    case "fn":
+                        return (name == "method" || name == "tymethod");
+                    case "type":
+                        return (name == "primitive");
+                }
+
+                // No match
+                return false;
+            }
+
             // quoted values mean literal search
             var nSearchWords = searchWords.length;
             if ((val.charAt(0) === "\"" || val.charAt(0) === "'") &&
@@ -239,7 +261,7 @@
                 for (var i = 0; i < nSearchWords; ++i) {
                     if (searchWords[i] === val) {
                         // filter type: ... queries
-                        if (typeFilter < 0 || typeFilter === searchIndex[i].ty) {
+                        if (typePassesFilter(typeFilter, searchIndex[i].ty)) {
                             results.push({id: i, index: -1});
                         }
                     }
@@ -285,7 +307,7 @@
                             searchWords[j].replace(/_/g, "").indexOf(val) > -1)
                         {
                             // filter type: ... queries
-                            if (typeFilter < 0 || typeFilter === searchIndex[j].ty) {
+                            if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
                                 results.push({
                                     id: j,
                                     index: searchWords[j].replace(/_/g, "").indexOf(val),
@@ -295,7 +317,7 @@
                         } else if (
                             (lev_distance = levenshtein(searchWords[j], val)) <=
                                 MAX_LEV_DISTANCE) {
-                            if (typeFilter < 0 || typeFilter === searchIndex[j].ty) {
+                            if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
                                 results.push({
                                     id: j,
                                     index: 0,
@@ -451,11 +473,9 @@
             var matches, type, query, raw = $('.search-input').val();
             query = raw;
 
-            matches = query.match(/^(fn|mod|struct|enum|trait|t(ype)?d(ef)?)\s*:\s*/i);
+            matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);
             if (matches) {
-                type = matches[1].replace(/^td$/, 'typedef')
-                                 .replace(/^tdef$/, 'typedef')
-                                 .replace(/^typed$/, 'typedef');
+                type = matches[1].replace(/^const$/, 'constant');
                 query = query.substring(matches[0].length);
             }
 
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index bc6c797e5c5..a311b938e96 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -29,13 +29,14 @@ use test::{TestOptions, Collector};
 /// Separate any lines at the start of the file that begin with `%`.
 fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
     let mut metadata = Vec::new();
+    let mut count = 0;
     for line in s.lines() {
         if line.starts_with("%") {
             // remove %<whitespace>
-            metadata.push(line[1..].trim_left())
+            metadata.push(line[1..].trim_left());
+            count += line.len() + 1;
         } else {
-            let line_start_byte = s.find(line).unwrap();
-            return (metadata, &s[line_start_byte..]);
+            return (metadata, &s[count..]);
         }
     }
     // if we're here, then all lines were metadata % lines.
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index e7430f698e9..4b31a606931 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// VecMap
+#![allow(deprecated)]
+
 //! Implementations of serialization for structures found in libcollections
 
 use std::usize;
diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs
index 87f1dca2cae..609ebe85461 100644
--- a/src/libserialize/hex.rs
+++ b/src/libserialize/hex.rs
@@ -30,7 +30,8 @@ impl ToHex for [u8] {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(rustc_private)]
+    /// #![feature(rustc_private)]
+    ///
     /// extern crate serialize;
     /// use serialize::hex::ToHex;
     ///
@@ -100,7 +101,8 @@ impl FromHex for str {
     /// This converts a string literal to hexadecimal and back.
     ///
     /// ```
-    /// # #![feature(rustc_private)]
+    /// #![feature(rustc_private)]
+    ///
     /// extern crate serialize;
     /// use serialize::hex::{FromHex, ToHex};
     ///
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index ac98282ebb8..cd9dadd1be9 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -125,7 +125,8 @@ pub trait AsciiExt {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(ascii)]
+    /// #![feature(ascii)]
+    ///
     /// use std::ascii::AsciiExt;
     ///
     /// let mut ascii = 'a';
@@ -144,7 +145,8 @@ pub trait AsciiExt {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(ascii)]
+    /// #![feature(ascii)]
+    ///
     /// use std::ascii::AsciiExt;
     ///
     /// let mut ascii = 'A';
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 06a30670e8b..66f894fc31f 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -543,7 +543,8 @@ impl<K, V, S> HashMap<K, V, S>
     /// # Examples
     ///
     /// ```
-    /// # #![feature(hashmap_hasher)]
+    /// #![feature(hashmap_hasher)]
+    ///
     /// use std::collections::HashMap;
     /// use std::collections::hash_map::RandomState;
     ///
@@ -572,7 +573,8 @@ impl<K, V, S> HashMap<K, V, S>
     /// # Examples
     ///
     /// ```
-    /// # #![feature(hashmap_hasher)]
+    /// #![feature(hashmap_hasher)]
+    ///
     /// use std::collections::HashMap;
     /// use std::collections::hash_map::RandomState;
     ///
@@ -979,7 +981,8 @@ impl<K, V, S> HashMap<K, V, S>
     /// # Examples
     ///
     /// ```
-    /// # #![feature(drain)]
+    /// #![feature(drain)]
+    ///
     /// use std::collections::HashMap;
     ///
     /// let mut a = HashMap::new();
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index ba50b156ab2..fb594dadd73 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -154,7 +154,8 @@ impl<T, S> HashSet<T, S>
     /// # Examples
     ///
     /// ```
-    /// # #![feature(hashmap_hasher)]
+    /// #![feature(hashmap_hasher)]
+    ///
     /// use std::collections::HashSet;
     /// use std::collections::hash_map::RandomState;
     ///
@@ -179,7 +180,8 @@ impl<T, S> HashSet<T, S>
     /// # Examples
     ///
     /// ```
-    /// # #![feature(hashmap_hasher)]
+    /// #![feature(hashmap_hasher)]
+    ///
     /// use std::collections::HashSet;
     /// use std::collections::hash_map::RandomState;
     ///
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index b21b2edf2ec..4d08f08bb6e 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -168,7 +168,7 @@ impl Error for string::FromUtf16Error {
 // copied from any.rs
 impl Error + 'static {
     /// Returns true if the boxed type is the same as `T`
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn is<T: Error + 'static>(&self) -> bool {
         // Get TypeId of the type this function is instantiated with
@@ -183,7 +183,7 @@ impl Error + 'static {
 
     /// Returns some reference to the boxed value if it is of type `T`, or
     /// `None` if it isn't.
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
         if self.is::<T>() {
@@ -201,7 +201,7 @@ impl Error + 'static {
 
     /// Returns some mutable reference to the boxed value if it is of type `T`, or
     /// `None` if it isn't.
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
@@ -220,21 +220,44 @@ impl Error + 'static {
 
 impl Error + 'static + Send {
     /// Forwards to the method defined on the type `Any`.
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn is<T: Error + 'static>(&self) -> bool {
         <Error + 'static>::is::<T>(self)
     }
 
     /// Forwards to the method defined on the type `Any`.
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
         <Error + 'static>::downcast_ref::<T>(self)
     }
 
     /// Forwards to the method defined on the type `Any`.
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
+    #[inline]
+    pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
+        <Error + 'static>::downcast_mut::<T>(self)
+    }
+}
+
+impl Error + 'static + Send + Sync {
+    /// Forwards to the method defined on the type `Any`.
+    #[stable(feature = "error_downcast", since = "1.3.0")]
+    #[inline]
+    pub fn is<T: Error + 'static>(&self) -> bool {
+        <Error + 'static>::is::<T>(self)
+    }
+
+    /// Forwards to the method defined on the type `Any`.
+    #[stable(feature = "error_downcast", since = "1.3.0")]
+    #[inline]
+    pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
+        <Error + 'static>::downcast_ref::<T>(self)
+    }
+
+    /// Forwards to the method defined on the type `Any`.
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
         <Error + 'static>::downcast_mut::<T>(self)
@@ -243,7 +266,7 @@ impl Error + 'static + Send {
 
 impl Error {
     #[inline]
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     /// Attempt to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
         if self.is::<T>() {
@@ -264,9 +287,10 @@ impl Error {
 
 impl Error + Send {
     #[inline]
-    #[unstable(feature = "error_downcast", reason = "recently added")]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
     /// Attempt to downcast the box to a concrete type.
-    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error + Send>> {
+    pub fn downcast<T: Error + 'static>(self: Box<Self>)
+                                        -> Result<Box<T>, Box<Error + Send>> {
         let err: Box<Error> = self;
         <Error>::downcast(err).map_err(|s| unsafe {
             // reapply the Send marker
@@ -274,3 +298,63 @@ impl Error + Send {
         })
     }
 }
+
+impl Error + Send + Sync {
+    #[inline]
+    #[stable(feature = "error_downcast", since = "1.3.0")]
+    /// Attempt to downcast the box to a concrete type.
+    pub fn downcast<T: Error + 'static>(self: Box<Self>)
+                                        -> Result<Box<T>, Box<Self>> {
+        let err: Box<Error> = self;
+        <Error>::downcast(err).map_err(|s| unsafe {
+            // reapply the Send+Sync marker
+            transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::v1::*;
+    use super::Error;
+    use fmt;
+
+    #[derive(Debug, PartialEq)]
+    struct A;
+    #[derive(Debug, PartialEq)]
+    struct B;
+
+    impl fmt::Display for A {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            write!(f, "A")
+        }
+    }
+    impl fmt::Display for B {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            write!(f, "B")
+        }
+    }
+
+    impl Error for A {
+        fn description(&self) -> &str { "A-desc" }
+    }
+    impl Error for B {
+        fn description(&self) -> &str { "A-desc" }
+    }
+
+    #[test]
+    fn downcasting() {
+        let mut a = A;
+        let mut a = &mut a as &mut (Error + 'static);
+        assert_eq!(a.downcast_ref::<A>(), Some(&A));
+        assert_eq!(a.downcast_ref::<B>(), None);
+        assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
+        assert_eq!(a.downcast_mut::<B>(), None);
+
+        let a: Box<Error> = Box::new(A);
+        match a.downcast::<B>() {
+            Ok(..) => panic!("expected error"),
+            Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
+        }
+    }
+}
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index c9fe6e7e0b1..6eb0719d9f6 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -11,7 +11,6 @@
 use ascii;
 use borrow::{Cow, ToOwned, Borrow};
 use boxed::Box;
-use clone::Clone;
 use convert::{Into, From};
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use error::Error;
@@ -62,7 +61,7 @@ use vec::Vec;
 /// }
 /// # }
 /// ```
-#[derive(PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct CString {
     inner: Box<[u8]>,
@@ -251,13 +250,6 @@ impl CString {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for CString {
-    fn clone(&self) -> Self {
-        CString { inner: self.inner.to_owned().into_boxed_slice() }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
 impl Deref for CString {
     type Target = CStr;
 
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 29d1fe19adf..eca6ffc8ce3 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -407,8 +407,6 @@ impl<W: Write> BufWriter<W> {
 
     /// Gets a mutable reference to the underlying writer.
     ///
-    /// # Warning
-    ///
     /// It is inadvisable to directly write to the underlying writer.
     ///
     /// # Examples
@@ -835,8 +833,6 @@ impl<S: Read + Write> BufStream<S> {
 
     /// Gets a mutable reference to the underlying stream.
     ///
-    /// # Warning
-    ///
     /// It is inadvisable to read directly from or write directly to the
     /// underlying stream.
     pub fn get_mut(&mut self) -> &mut S {
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 4bb7d2ebd19..980ec51c926 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -15,10 +15,8 @@ use cmp;
 use io::{self, SeekFrom, Error, ErrorKind};
 use slice;
 
-/// A `Cursor` wraps another type and provides it with a [`Seek`][seek]
-/// implementation.
-///
-/// [seek]: trait.Seek.html
+/// A `Cursor` wraps another type and provides it with a
+/// [`Seek`](trait.Seek.html) implementation.
 ///
 /// Cursors are typically used with in-memory buffers to allow them to
 /// implement `Read` and/or `Write`, allowing these buffers to be used
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index 3b48ff30960..e12e202148b 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -219,8 +219,7 @@ impl Error {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
-    #[unstable(feature = "io_error_inner",
-               reason = "recently added and requires UFCS to downcast")]
+    #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
         match self.repr {
             Repr::Os(..) => None,
@@ -233,8 +232,7 @@ impl Error {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
-    #[unstable(feature = "io_error_inner",
-               reason = "recently added and requires UFCS to downcast")]
+    #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
         match self.repr {
             Repr::Os(..) => None,
@@ -246,8 +244,7 @@ impl Error {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
-    #[unstable(feature = "io_error_inner",
-               reason = "recently added and requires UFCS to downcast")]
+    #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
         match self.repr {
             Repr::Os(..) => None,
@@ -349,10 +346,10 @@ mod test {
         // we have to call all of these UFCS style right now since method
         // resolution won't implicitly drop the Send+Sync bounds
         let mut err = Error::new(ErrorKind::Other, TestError);
-        assert!(error::Error::is::<TestError>(err.get_ref().unwrap()));
+        assert!(err.get_ref().unwrap().is::<TestError>());
         assert_eq!("asdf", err.get_ref().unwrap().description());
-        assert!(error::Error::is::<TestError>(err.get_mut().unwrap()));
+        assert!(err.get_mut().unwrap().is::<TestError>());
         let extracted = err.into_inner().unwrap();
-        error::Error::downcast::<TestError>(extracted).unwrap();
+        extracted.downcast::<TestError>().unwrap();
     }
 }
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index ffdd75b0e6e..3d746aa450a 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -707,7 +707,7 @@ pub trait Read {
     ///
     /// # fn foo() -> io::Result<()> {
     /// let mut f = try!(File::open("foo.txt"));
-    /// let mut buffer = [0; 10];
+    /// let mut buffer = [0; 5];
     ///
     /// // read at most five bytes
     /// let mut handle = f.take(5);
@@ -1060,8 +1060,9 @@ pub trait Seek {
     /// The behavior when seeking past the end of the stream is implementation
     /// defined.
     ///
-    /// This method returns the new position within the stream if the seek
-    /// operation completed successfully.
+    /// If the seek operation completed successfully,
+    /// this method returns the new position from the start of the stream.
+    /// That position can be used later with `SeekFrom::Start`.
     ///
     /// # Errors
     ///
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index d8b7c8a282c..d69e17cade4 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -255,7 +255,7 @@ impl Stdin {
     //    in which case it will wait for the Enter key to be pressed before
     ///   continuing
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
+    pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
         self.lock().read_line(buf)
     }
 }
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index dc29811ed5b..6e651464c74 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -105,7 +105,7 @@ impl BufRead for Empty {
 /// This struct is generally created by calling [`repeat()`][repeat]. Please
 /// see the documentation of `repeat()` for more details.
 ///
-/// [empty]: fn.repeat.html
+/// [repeat]: fn.repeat.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Repeat { byte: u8 }
 
@@ -131,7 +131,7 @@ impl Read for Repeat {
 /// This struct is generally created by calling [`sink()`][sink]. Please
 /// see the documentation of `sink()` for more details.
 ///
-/// [empty]: fn.sink.html
+/// [sink]: fn.sink.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Sink { _priv: () }
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 3d3a46e61d5..2e796004aab 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -13,12 +13,11 @@
 //! The Rust Standard Library is the foundation of portable Rust
 //! software, a set of minimal and battle-tested shared abstractions
 //! for the [broader Rust ecosystem](https://crates.io). It offers
-//! core types (e.g. [`Vec`](vec/index.html)
-//! and [`Option`](option/index.html)), library-defined [operations on
-//! language primitives](#primitive) (e.g. [`u32`](u32/index.html) and
-//! [`str`](str/index.html)), [standard macros](#macros),
+//! core types, like [`Vec`](vec/index.html)
+//! and [`Option`](option/index.html), library-defined [operations on
+//! language primitives](#primitives), [standard macros](#macros),
 //! [I/O](io/index.html) and [multithreading](thread/index.html), among
-//! [many other lovely
+//! [many other
 //! things](#what-is-in-the-standard-library-documentation?).
 //!
 //! `std` is available to all Rust crates by default, just as if each
@@ -65,8 +64,6 @@
 //!
 //! # What is in the standard library documentation?
 //!
-//! Lots of stuff. Well, broadly four things actually.
-//!
 //! First of all, The Rust Standard Library is divided into a number
 //! of focused modules, [all listed further down this page](#modules).
 //! These modules are the bedrock upon which all of Rust is forged,
@@ -89,7 +86,7 @@
 //!
 //! So for example there is a [page for the primitive type
 //! `i32`](primitive.i32.html) that lists all the methods that can be
-//! called on 32-bit integers (mega useful), and there is a [page for
+//! called on 32-bit integers (very useful), and there is a [page for
 //! the module `std::i32`](i32/index.html) that documents the constant
 //! values `MIN` and `MAX` (rarely useful).
 //!
@@ -99,9 +96,7 @@
 //! [`String`](string/struct.String.html) and
 //! [`Vec`](vec/struct.Vec.html) are actually calls to methods on
 //! `str` and `[T]` respectively, via [deref
-//! coercions](../book/deref-coercions.html). *Accepting that
-//! primitive types are documented on their own pages will bring you a
-//! deep inner wisdom. Embrace it now before proceeding.*
+//! coercions](../book/deref-coercions.html).
 //!
 //! Third, the standard library defines [The Rust
 //! Prelude](prelude/index.html), a small collection of items - mostly
@@ -281,28 +276,23 @@ extern crate libc;
 
 #[macro_use] #[no_link] extern crate rustc_bitflags;
 
-// Make std testable by not duplicating lang items. See #2912
+// Make std testable by not duplicating lang items and other globals. See #2912
 #[cfg(test)] extern crate std as realstd;
-#[cfg(test)] pub use realstd::marker;
-#[cfg(test)] pub use realstd::ops;
-#[cfg(test)] pub use realstd::cmp;
-#[cfg(test)] pub use realstd::boxed;
-
 
 // NB: These reexports are in the order they should be listed in rustdoc
 
 pub use core::any;
 pub use core::cell;
 pub use core::clone;
-#[cfg(not(test))] pub use core::cmp;
+pub use core::cmp;
 pub use core::convert;
 pub use core::default;
 pub use core::hash;
 pub use core::intrinsics;
 pub use core::iter;
-#[cfg(not(test))] pub use core::marker;
+pub use core::marker;
 pub use core::mem;
-#[cfg(not(test))] pub use core::ops;
+pub use core::ops;
 pub use core::ptr;
 pub use core::raw;
 pub use core::simd;
@@ -310,7 +300,7 @@ pub use core::result;
 pub use core::option;
 pub mod error;
 
-#[cfg(not(test))] pub use alloc::boxed;
+pub use alloc::boxed;
 pub use alloc::rc;
 
 pub use core_collections::borrow;
@@ -421,27 +411,10 @@ pub mod __rand {
 // because rustdoc only looks for these modules at the crate level.
 include!("primitive_docs.rs");
 
-// A curious inner-module that's not exported that contains the binding
-// 'std' so that macro-expanded references to std::error and such
-// can be resolved within libstd.
-#[doc(hidden)]
+// The expansion of --test has a few references to `::std::$foo` so this module
+// is necessary to get things to compile.
+#[cfg(test)]
 mod std {
-    pub use sync; // used for select!()
-    pub use error; // used for try!()
-    pub use fmt; // used for any formatting strings
-    pub use option; // used for thread_local!{}
-    pub use rt; // used for panic!()
-    pub use vec; // used for vec![]
-    pub use cell; // used for tls!
-    pub use thread; // used for thread_local!
-    pub use marker;  // used for tls!
-
-    // The test runner calls ::std::env::args() but really wants realstd
-    #[cfg(test)] pub use realstd::env as env;
-    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
-    //
-    // It is also used in vec![]
-    pub use slice;
-
-    pub use boxed; // used for vec![]
+    pub use option;
+    pub use realstd::env;
 }
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 697b934c676..eb378bf4080 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -141,7 +141,8 @@ macro_rules! try {
 /// # Examples
 ///
 /// ```
-/// # #![feature(mpsc_select)]
+/// #![feature(mpsc_select)]
+///
 /// use std::thread;
 /// use std::sync::mpsc;
 ///
diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs
index 1cb8c187030..c7daf5cdee5 100644
--- a/src/libstd/net/mod.rs
+++ b/src/libstd/net/mod.rs
@@ -103,7 +103,8 @@ impl Iterator for LookupHost {
 /// # Examples
 ///
 /// ```no_run
-/// # #![feature(lookup_host)]
+/// #![feature(lookup_host)]
+///
 /// use std::net;
 ///
 /// # fn foo() -> std::io::Result<()> {
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index c410233df92..84e05083b57 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -129,6 +129,9 @@ impl TcpStream {
     }
 
     /// Sets the nodelay flag on this connection to the boolean specified.
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
+    #[unstable(feature = "tcp_extras", reason = "available externally")]
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
         self.0.set_nodelay(nodelay)
     }
@@ -138,6 +141,9 @@ impl TcpStream {
     /// If the value specified is `None`, then the keepalive flag is cleared on
     /// this connection. Otherwise, the keepalive timeout will be set to the
     /// specified time, in seconds.
+    #[unstable(feature = "tcp_extras", reason = "available externally")]
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
     pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
         self.0.set_keepalive(seconds)
     }
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index a98ccc38735..8212b8888d3 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -98,6 +98,9 @@ impl UdpSocket {
     }
 
     /// Sets the broadcast flag on or off.
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
+    #[unstable(feature = "udp_extras", reason = "available externally")]
     pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
         self.0.set_broadcast(on)
     }
@@ -105,26 +108,41 @@ impl UdpSocket {
     /// Sets the multicast loop flag to the specified value.
     ///
     /// This lets multicast packets loop back to local sockets (if enabled)
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
+    #[unstable(feature = "udp_extras", reason = "available externally")]
     pub fn set_multicast_loop(&self, on: bool) -> io::Result<()> {
         self.0.set_multicast_loop(on)
     }
 
     /// Joins a multicast IP address (becomes a member of it).
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
+    #[unstable(feature = "udp_extras", reason = "available externally")]
     pub fn join_multicast(&self, multi: &IpAddr) -> io::Result<()> {
         self.0.join_multicast(multi)
     }
 
     /// Leaves a multicast IP address (drops membership from it).
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
+    #[unstable(feature = "udp_extras", reason = "available externally")]
     pub fn leave_multicast(&self, multi: &IpAddr) -> io::Result<()> {
         self.0.leave_multicast(multi)
     }
 
     /// Sets the multicast TTL.
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
+    #[unstable(feature = "udp_extras", reason = "available externally")]
     pub fn set_multicast_time_to_live(&self, ttl: i32) -> io::Result<()> {
         self.0.multicast_time_to_live(ttl)
     }
 
     /// Sets this socket's TTL.
+    #[deprecated(since = "1.3.0",
+                 reason = "available through the `net2` crate on crates.io")]
+    #[unstable(feature = "udp_extras", reason = "available externally")]
     pub fn set_time_to_live(&self, ttl: i32) -> io::Result<()> {
         self.0.time_to_live(ttl)
     }
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 9d0b9c3bbb4..73d6639cf00 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -235,7 +235,8 @@ impl f32 {
     /// The floating point encoding is documented in the [Reference][floating-point].
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// use std::f32;
     ///
     /// let num = 2.0f32;
@@ -598,7 +599,8 @@ impl f32 {
     /// Converts radians to degrees.
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// use std::f32::{self, consts};
     ///
     /// let angle = consts::PI;
@@ -614,7 +616,8 @@ impl f32 {
     /// Converts degrees to radians.
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// use std::f32::{self, consts};
     ///
     /// let angle = 180.0f32;
@@ -630,7 +633,8 @@ impl f32 {
     /// Constructs a floating point number of `x*2^exp`.
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// use std::f32;
     /// // 3*2^2 - 12 == 0
     /// let abs_difference = (f32::ldexp(3.0, 2) - 12.0).abs();
@@ -651,7 +655,8 @@ impl f32 {
     ///  * `0.5 <= abs(x) < 1.0`
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// use std::f32;
     ///
     /// let x = 4.0f32;
@@ -679,7 +684,8 @@ impl f32 {
     /// `other`.
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// use std::f32;
     ///
     /// let x = 1.0f32;
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 4f2f59659ac..3911d276b0f 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -191,7 +191,8 @@ impl f64 {
     /// The floating point encoding is documented in the [Reference][floating-point].
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// let num = 2.0f64;
     ///
     /// // (8388608, -22, 1)
@@ -568,7 +569,8 @@ impl f64 {
     /// Constructs a floating point number of `x*2^exp`.
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// // 3*2^2 - 12 == 0
     /// let abs_difference = (f64::ldexp(3.0, 2) - 12.0).abs();
     ///
@@ -588,7 +590,8 @@ impl f64 {
     ///  * `0.5 <= abs(x) < 1.0`
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
+    ///
     /// let x = 4.0_f64;
     ///
     /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
@@ -614,7 +617,7 @@ impl f64 {
     /// `other`.
     ///
     /// ```
-    /// # #![feature(float_extras)]
+    /// #![feature(float_extras)]
     ///
     /// let x = 1.0f32;
     ///
diff --git a/src/libstd/os/freebsd/raw.rs b/src/libstd/os/freebsd/raw.rs
index 38e31a3c5ac..65390aee0e1 100644
--- a/src/libstd/os/freebsd/raw.rs
+++ b/src/libstd/os/freebsd/raw.rs
@@ -12,73 +12,130 @@
 
 #![stable(feature = "raw_ext", since = "1.1.0")]
 
-use os::raw::c_long;
-use os::unix::raw::{uid_t, gid_t};
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u16;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u16;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32;
 
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type blkcnt_t = i64;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type blksize_t = i64;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type dev_t = u32;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type fflags_t = u32;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type ino_t = u32;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type mode_t = u16;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type nlink_t = u16;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type off_t = i64;
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub type time_t = i64;
+#[doc(inline)]
+pub use self::arch::{stat, time_t};
 
-#[repr(C)]
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub struct stat {
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_dev: dev_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ino: ino_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mode: mode_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_nlink: nlink_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_uid: uid_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_gid: gid_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_rdev: dev_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_atime: time_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_atime_nsec: c_long,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mtime: time_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mtime_nsec: c_long,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ctime: time_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ctime_nsec: c_long,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_size: off_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_blocks: blkcnt_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_blksize: blksize_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_flags: fflags_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_gen: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_lspare: i32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_birthtime: time_t,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_birthtime_nsec: c_long,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub __unused: [u8; 2],
+#[cfg(target_arch = "x86")]
+mod arch {
+    use super::{off_t, dev_t, ino_t, mode_t, nlink_t, blksize_t, blkcnt_t, fflags_t};
+    use os::raw::c_long;
+    use os::unix::raw::{uid_t, gid_t};
+
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32;
+
+    #[repr(C)]
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub struct stat {
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_dev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ino: ino_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mode: mode_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_nlink: nlink_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_uid: uid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_gid: gid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_rdev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime_nsec: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime_nsec: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime_nsec: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_size: off_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blocks: blkcnt_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blksize: blksize_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_flags: fflags_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_gen: u32,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_lspare: i32,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_birthtime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_birthtime_nsec: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub __unused: [u8; 8],
+    }
 }
+
+#[cfg(target_arch = "x86_64")]
+mod arch {
+    use super::{off_t, dev_t, ino_t, mode_t, nlink_t, blksize_t, blkcnt_t, fflags_t};
+    use os::raw::c_long;
+    use os::unix::raw::{uid_t, gid_t};
+
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
+
+    #[repr(C)]
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub struct stat {
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_dev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ino: ino_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mode: mode_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_nlink: nlink_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_uid: uid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_gid: gid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_rdev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime_nsec: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime_nsec: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime_nsec: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_size: off_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blocks: blkcnt_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blksize: blksize_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_flags: fflags_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_gen: u32,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_lspare: i32,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_birthtime: time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_birthtime_nsec: c_long,
+    }
+}
+
+
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
index 275f415c6fc..4597db41e90 100644
--- a/src/libstd/prelude/mod.rs
+++ b/src/libstd/prelude/mod.rs
@@ -11,8 +11,8 @@
 //! 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
+//! imported at the topmost level of every crate by default, as if
+//! each crate contains the following:
 //!
 //! ```ignore
 //! extern crate std;
@@ -23,7 +23,7 @@
 //! etc.
 //!
 //! Additionally, `std` contains a versioned *prelude* that reexports many of the
-//! most common traits, types and functions. *The contents of the prelude are
+//! 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 [`use` statement][book-use]:
 //!
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 066b2b576da..7f14ea93c52 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -111,7 +111,8 @@ mod prim_unit { }
 /// the raw pointer. It doesn't destroy `T` or deallocate any memory.
 ///
 /// ```
-/// # #![feature(box_raw)]
+/// #![feature(box_raw)]
+///
 /// let my_speed: Box<i32> = Box::new(88);
 /// let my_speed: *mut i32 = Box::into_raw(my_speed);
 ///
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 3471805b2bc..74a66558627 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -505,7 +505,7 @@ impl Child {
     }
 
     /// Returns the OS-assigned process identifier associated with this child.
-    #[unstable(feature = "process_id", reason = "api recently added")]
+    #[stable(feature = "process_id", since = "1.3.0")]
     pub fn id(&self) -> u32 {
         self.handle.id()
     }
@@ -591,7 +591,6 @@ mod tests {
     use io::prelude::*;
 
     use io::ErrorKind;
-    use rt::running_on_valgrind;
     use str;
     use super::{Command, Output, Stdio};
 
@@ -737,10 +736,7 @@ mod tests {
 
         assert!(status.success());
         assert_eq!(output_str.trim().to_string(), "hello");
-        // FIXME #7224
-        if !running_on_valgrind() {
-            assert_eq!(stderr, Vec::new());
-        }
+        assert_eq!(stderr, Vec::new());
     }
 
     #[cfg(not(target_os="android"))]
@@ -779,10 +775,7 @@ mod tests {
 
         assert!(status.success());
         assert_eq!(output_str.trim().to_string(), "hello");
-        // FIXME #7224
-        if !running_on_valgrind() {
-            assert_eq!(stderr, Vec::new());
-        }
+        assert_eq!(stderr, Vec::new());
     }
 
     #[cfg(all(unix, not(target_os="android")))]
@@ -806,8 +799,7 @@ mod tests {
     #[cfg(not(target_os="android"))]
     #[test]
     fn test_inherit_env() {
-        use std::env;
-        if running_on_valgrind() { return; }
+        use env;
 
         let result = env_cmd().output().unwrap();
         let output = String::from_utf8(result.stdout).unwrap();
@@ -824,7 +816,6 @@ mod tests {
     #[test]
     fn test_inherit_env() {
         use std::env;
-        if running_on_valgrind() { return; }
 
         let mut result = env_cmd().output().unwrap();
         let output = String::from_utf8(result.stdout).unwrap();
diff --git a/src/libstd/rt/dwarf/eh.rs b/src/libstd/rt/dwarf/eh.rs
new file mode 100644
index 00000000000..990501b28db
--- /dev/null
+++ b/src/libstd/rt/dwarf/eh.rs
@@ -0,0 +1,159 @@
+// 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.
+
+//! Parsing of GCC-style Language-Specific Data Area (LSDA)
+//! For details see:
+//!   http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html
+//!   http://mentorembedded.github.io/cxx-abi/exceptions.pdf
+//!   http://www.airs.com/blog/archives/460
+//!   http://www.airs.com/blog/archives/464
+//!
+//! A reference implementation may be found in the GCC source tree
+//! (<root>/libgcc/unwind-c.c as of this writing)
+
+#![allow(non_upper_case_globals)]
+#![allow(unused)]
+
+use prelude::v1::*;
+use rt::dwarf::DwarfReader;
+use core::mem;
+
+pub const DW_EH_PE_omit     : u8 = 0xFF;
+pub const DW_EH_PE_absptr   : u8 = 0x00;
+
+pub const DW_EH_PE_uleb128  : u8 = 0x01;
+pub const DW_EH_PE_udata2   : u8 = 0x02;
+pub const DW_EH_PE_udata4   : u8 = 0x03;
+pub const DW_EH_PE_udata8   : u8 = 0x04;
+pub const DW_EH_PE_sleb128  : u8 = 0x09;
+pub const DW_EH_PE_sdata2   : u8 = 0x0A;
+pub const DW_EH_PE_sdata4   : u8 = 0x0B;
+pub const DW_EH_PE_sdata8   : u8 = 0x0C;
+
+pub const DW_EH_PE_pcrel    : u8 = 0x10;
+pub const DW_EH_PE_textrel  : u8 = 0x20;
+pub const DW_EH_PE_datarel  : u8 = 0x30;
+pub const DW_EH_PE_funcrel  : u8 = 0x40;
+pub const DW_EH_PE_aligned  : u8 = 0x50;
+
+pub const DW_EH_PE_indirect : u8 = 0x80;
+
+#[derive(Copy, Clone)]
+pub struct EHContext {
+    pub ip: usize,         // Current instruction pointer
+    pub func_start: usize, // Address of the current function
+    pub text_start: usize, // Address of the code section
+    pub data_start: usize, // Address of the data section
+}
+
+pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
+                               -> Option<usize> {
+    if lsda.is_null() {
+        return None;
+    }
+
+    let func_start = context.func_start;
+    let mut reader = DwarfReader::new(lsda);
+
+    let start_encoding = reader.read::<u8>();
+    // base address for landing pad offsets
+    let lpad_base = if start_encoding != DW_EH_PE_omit {
+        read_encoded_pointer(&mut reader, context, start_encoding)
+    } else {
+        func_start
+    };
+
+    let ttype_encoding = reader.read::<u8>();
+    if ttype_encoding != DW_EH_PE_omit {
+        // Rust doesn't analyze exception types, so we don't care about the type table
+        reader.read_uleb128();
+    }
+
+    let call_site_encoding = reader.read::<u8>();
+    let call_site_table_length = reader.read_uleb128();
+    let action_table = reader.ptr.offset(call_site_table_length as isize);
+    // Return addresses point 1 byte past the call instruction, which could
+    // be in the next IP range.
+    let ip = context.ip-1;
+
+    while reader.ptr < action_table {
+        let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding);
+        let cs_len = read_encoded_pointer(&mut reader, context, call_site_encoding);
+        let cs_lpad = read_encoded_pointer(&mut reader, context, call_site_encoding);
+        let cs_action = reader.read_uleb128();
+        // Callsite table is sorted by cs_start, so if we've passed the ip, we
+        // may stop searching.
+        if ip < func_start + cs_start {
+            break
+        }
+        if ip < func_start + cs_start + cs_len {
+            if cs_lpad != 0 {
+                return Some(lpad_base + cs_lpad);
+            } else {
+                return None;
+            }
+        }
+    }
+    // IP range not found: gcc's C++ personality calls terminate() here,
+    // however the rest of the languages treat this the same as cs_lpad == 0.
+    // We follow this suit.
+    return None;
+}
+
+#[inline]
+fn round_up(unrounded: usize, align: usize) -> usize {
+    assert!(align.is_power_of_two());
+    (unrounded + align - 1) & !(align - 1)
+}
+
+unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
+                               context: &EHContext,
+                               encoding: u8) -> usize {
+    assert!(encoding != DW_EH_PE_omit);
+
+    // DW_EH_PE_aligned implies it's an absolute pointer value
+    if encoding == DW_EH_PE_aligned {
+        reader.ptr = round_up(reader.ptr as usize,
+                              mem::size_of::<usize>()) as *const u8;
+        return reader.read::<usize>();
+    }
+
+    let mut result = match encoding & 0x0F {
+        DW_EH_PE_absptr => reader.read::<usize>(),
+        DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
+        DW_EH_PE_udata2 => reader.read::<u16>() as usize,
+        DW_EH_PE_udata4 => reader.read::<u32>() as usize,
+        DW_EH_PE_udata8 => reader.read::<u64>() as usize,
+        DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
+        DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
+        DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
+        DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
+        _ => panic!()
+    };
+
+    result += match encoding & 0x70 {
+        DW_EH_PE_absptr => 0,
+        // relative to address of the encoded value, despite the name
+        DW_EH_PE_pcrel => reader.ptr as usize,
+        DW_EH_PE_textrel => { assert!(context.text_start != 0);
+                              context.text_start },
+        DW_EH_PE_datarel => { assert!(context.data_start != 0);
+                              context.data_start },
+        DW_EH_PE_funcrel => { assert!(context.func_start != 0);
+                              context.func_start },
+        _ => panic!()
+    };
+
+    if encoding & DW_EH_PE_indirect != 0 {
+        result = *(result as *const usize);
+    }
+
+    result
+}
diff --git a/src/libstd/rt/dwarf/mod.rs b/src/libstd/rt/dwarf/mod.rs
new file mode 100644
index 00000000000..822826bcc83
--- /dev/null
+++ b/src/libstd/rt/dwarf/mod.rs
@@ -0,0 +1,107 @@
+// 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.
+
+//! Utilities for parsing DWARF-encoded data streams.
+//! See http://www.dwarfstd.org,
+//! DWARF-4 standard, Section 7 - "Data Representation"
+
+// This module is used only by x86_64-pc-windows-gnu for now, but we
+// are compiling it everywhere to avoid regressions.
+#![allow(unused)]
+
+pub mod eh;
+
+use prelude::v1::*;
+use core::mem;
+
+pub struct DwarfReader {
+    pub ptr : *const u8
+}
+
+#[repr(C,packed)]
+struct Unaligned<T>(T);
+
+impl DwarfReader {
+
+    pub fn new(ptr : *const u8) -> DwarfReader {
+        DwarfReader {
+            ptr : ptr
+        }
+    }
+
+    // DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
+    // on a 4-byte boundary. This may cause problems on platforms with strict
+    // alignment requirements. By wrapping data in a "packed" struct, we are
+    // telling the backend to generate "misalignment-safe" code.
+    pub unsafe fn read<T:Copy>(&mut self) -> T {
+        let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
+        self.ptr = self.ptr.offset(mem::size_of::<T>() as isize);
+        result
+    }
+
+    // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
+    // Length Data".
+    pub unsafe fn read_uleb128(&mut self) -> u64 {
+        let mut shift : usize = 0;
+        let mut result : u64 = 0;
+        let mut byte : u8;
+        loop {
+            byte = self.read::<u8>();
+            result |= ((byte & 0x7F) as u64) << shift;
+            shift += 7;
+            if byte & 0x80 == 0 {
+                break;
+            }
+        }
+        result
+    }
+
+    pub unsafe fn read_sleb128(&mut self) -> i64 {
+        let mut shift : usize = 0;
+        let mut result : u64 = 0;
+        let mut byte : u8;
+        loop {
+            byte = self.read::<u8>();
+            result |= ((byte & 0x7F) as u64) << shift;
+            shift += 7;
+            if byte & 0x80 == 0 {
+                break;
+            }
+        }
+        // sign-extend
+        if shift < 8 * mem::size_of::<u64>() && (byte & 0x40) != 0 {
+            result |= (!0 as u64) << shift;
+        }
+        result as i64
+    }
+}
+
+#[test]
+fn dwarf_reader() {
+    let encoded: &[u8] = &[1,
+                           2, 3,
+                           4, 5, 6, 7,
+                           0xE5, 0x8E, 0x26,
+                           0x9B, 0xF1, 0x59,
+                           0xFF, 0xFF];
+
+    let mut reader = DwarfReader::new(encoded.as_ptr());
+
+    unsafe {
+        assert!(reader.read::<u8>() == u8::to_be(1u8));
+        assert!(reader.read::<u16>() == u16::to_be(0x0203));
+        assert!(reader.read::<u32>() == u32::to_be(0x04050607));
+
+        assert!(reader.read_uleb128() == 624485);
+        assert!(reader.read_sleb128() == -624485);
+
+        assert!(reader.read::<i8>() == i8::to_be(-1));
+    }
+}
diff --git a/src/libstd/rt/libunwind.rs b/src/libstd/rt/libunwind.rs
index d99b31c9f2b..fde612014e9 100644
--- a/src/libstd/rt/libunwind.rs
+++ b/src/libstd/rt/libunwind.rs
@@ -36,6 +36,7 @@ pub enum _Unwind_Action {
 
 #[cfg(target_arch = "arm")]
 #[repr(C)]
+#[derive(Copy, Clone)]
 pub enum _Unwind_State {
     _US_VIRTUAL_UNWIND_FRAME = 0,
     _US_UNWIND_FRAME_STARTING = 1,
@@ -46,6 +47,7 @@ pub enum _Unwind_State {
 }
 
 #[repr(C)]
+#[derive(Copy, Clone)]
 pub enum _Unwind_Reason_Code {
     _URC_NO_REASON = 0,
     _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
diff --git a/src/libstd/rt/macros.rs b/src/libstd/rt/macros.rs
index 1e3ab6d34da..414ccc911af 100644
--- a/src/libstd/rt/macros.rs
+++ b/src/libstd/rt/macros.rs
@@ -18,7 +18,7 @@ macro_rules! rterrln {
         ::rt::util::dumb_print(format_args!(concat!($fmt, "\n")))
     } );
     ($fmt:expr, $($arg:expr),*) => ( {
-        ::rt::util::dumb_print(format_args!(concat!($fmt, "\n"), $($arg)*))
+        ::rt::util::dumb_print(format_args!(concat!($fmt, "\n"), $($arg),*))
     } )
 }
 
@@ -31,7 +31,7 @@ macro_rules! rtdebug {
     } );
     ($str:expr, $($arg:expr),*) => ( {
         if cfg!(rtdebug) {
-            rterrln!($str, $($arg)*)
+            rterrln!($str, $($arg),*)
         }
     })
 }
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 0ac0d03e19d..56bf73db399 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -26,7 +26,7 @@ use sys;
 use usize;
 
 // Reexport some of our utilities which are expected by other crates.
-pub use self::util::{min_stack, running_on_valgrind};
+pub use self::util::min_stack;
 pub use self::unwind::{begin_unwind, begin_unwind_fmt};
 
 // Reexport some functionality from liballoc.
@@ -47,6 +47,8 @@ pub mod args;
 mod at_exit_imp;
 mod libunwind;
 
+mod dwarf;
+
 /// The default error code of the rust runtime if the main thread panics instead
 /// of exiting cleanly.
 pub const DEFAULT_ERROR_CODE: isize = 101;
diff --git a/src/libstd/rt/unwind/gcc.rs b/src/libstd/rt/unwind/gcc.rs
index 23e10ee6c39..55deb048b7e 100644
--- a/src/libstd/rt/unwind/gcc.rs
+++ b/src/libstd/rt/unwind/gcc.rs
@@ -74,14 +74,7 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
 //   so the behavior of __gcc_personality_v0 is perfectly adequate there, and
 // - rust_eh_personality_catch, used only by rust_try(), which always catches.
 //
-// Note, however, that for implementation simplicity, rust_eh_personality_catch
-// lacks code to install a landing pad, so in order to obtain exception object
-// pointer (which it needs to return upstream), rust_try() employs another trick:
-// it calls into the nested rust_try_inner(), whose landing pad does not resume
-// unwinds.  Instead, it extracts the exception pointer and performs a "normal"
-// return.
-//
-// See also: rt/rust_try.ll
+// See also: rustc_trans::trans::intrinsic::trans_gnu_try
 
 #[cfg(all(not(target_arch = "arm"),
           not(all(windows, target_arch = "x86_64")),
@@ -118,11 +111,11 @@ pub mod eabi {
     #[lang = "eh_personality_catch"]
     #[no_mangle]
     pub extern fn rust_eh_personality_catch(
-        _version: c_int,
+        version: c_int,
         actions: uw::_Unwind_Action,
-        _exception_class: uw::_Unwind_Exception_Class,
-        _ue_header: *mut uw::_Unwind_Exception,
-        _context: *mut uw::_Unwind_Context
+        exception_class: uw::_Unwind_Exception_Class,
+        ue_header: *mut uw::_Unwind_Exception,
+        context: *mut uw::_Unwind_Context
     ) -> uw::_Unwind_Reason_Code
     {
 
@@ -130,7 +123,10 @@ pub mod eabi {
             uw::_URC_HANDLER_FOUND // catch!
         }
         else { // cleanup phase
-            uw::_URC_INSTALL_CONTEXT
+            unsafe {
+                __gcc_personality_v0(version, actions, exception_class, ue_header,
+                                     context)
+            }
         }
     }
 }
@@ -171,11 +167,11 @@ pub mod eabi {
     #[lang = "eh_personality_catch"]
     #[no_mangle]
     pub extern fn rust_eh_personality_catch(
-        _version: c_int,
+        version: c_int,
         actions: uw::_Unwind_Action,
-        _exception_class: uw::_Unwind_Exception_Class,
-        _ue_header: *mut uw::_Unwind_Exception,
-        _context: *mut uw::_Unwind_Context
+        exception_class: uw::_Unwind_Exception_Class,
+        ue_header: *mut uw::_Unwind_Exception,
+        context: *mut uw::_Unwind_Context
     ) -> uw::_Unwind_Reason_Code
     {
         if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
@@ -183,8 +179,8 @@ pub mod eabi {
         }
         else { // cleanup phase
             unsafe {
-                __gcc_personality_sj0(_version, actions, _exception_class, _ue_header,
-                                      _context)
+                __gcc_personality_sj0(version, actions, exception_class, ue_header,
+                                      context)
             }
         }
     }
@@ -222,8 +218,8 @@ pub mod eabi {
     #[no_mangle]
     pub extern fn rust_eh_personality_catch(
         state: uw::_Unwind_State,
-        _ue_header: *mut uw::_Unwind_Exception,
-        _context: *mut uw::_Unwind_Context
+        ue_header: *mut uw::_Unwind_Exception,
+        context: *mut uw::_Unwind_Context
     ) -> uw::_Unwind_Reason_Code
     {
         if (state as c_int & uw::_US_ACTION_MASK as c_int)
@@ -231,112 +227,9 @@ pub mod eabi {
             uw::_URC_HANDLER_FOUND // catch!
         }
         else { // cleanup phase
-            uw::_URC_INSTALL_CONTEXT
-        }
-    }
-}
-
-// Win64 SEH (see http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx)
-//
-// This looks a bit convoluted because rather than implementing a native SEH
-// handler, GCC reuses the same personality routine as for the other
-// architectures by wrapping it with an "API translator" layer
-// (_GCC_specific_handler).
-
-#[cfg(all(windows, target_arch = "x86_64", not(test)))]
-#[doc(hidden)]
-#[allow(non_camel_case_types, non_snake_case)]
-pub mod eabi {
-    pub use self::EXCEPTION_DISPOSITION::*;
-    use rt::libunwind as uw;
-    use libc::{c_void, c_int};
-
-    // Fake definitions; these are actually complicated structs,
-    // but we don't use the contents here.
-    pub type EXCEPTION_RECORD = c_void;
-    pub type CONTEXT = c_void;
-    pub type DISPATCHER_CONTEXT = c_void;
-
-    #[repr(C)]
-    #[derive(Copy, Clone)]
-    pub enum EXCEPTION_DISPOSITION {
-        ExceptionContinueExecution,
-        ExceptionContinueSearch,
-        ExceptionNestedException,
-        ExceptionCollidedUnwind
-    }
-
-    type _Unwind_Personality_Fn =
-        extern fn(
-            version: c_int,
-            actions: uw::_Unwind_Action,
-            exception_class: uw::_Unwind_Exception_Class,
-            ue_header: *mut uw::_Unwind_Exception,
-            context: *mut uw::_Unwind_Context
-        ) -> uw::_Unwind_Reason_Code;
-
-    extern {
-        fn __gcc_personality_seh0(
-            exceptionRecord: *mut EXCEPTION_RECORD,
-            establisherFrame: *mut c_void,
-            contextRecord: *mut CONTEXT,
-            dispatcherContext: *mut DISPATCHER_CONTEXT
-        ) -> EXCEPTION_DISPOSITION;
-
-        fn _GCC_specific_handler(
-            exceptionRecord: *mut EXCEPTION_RECORD,
-            establisherFrame: *mut c_void,
-            contextRecord: *mut CONTEXT,
-            dispatcherContext: *mut DISPATCHER_CONTEXT,
-            personality: _Unwind_Personality_Fn
-        ) -> EXCEPTION_DISPOSITION;
-    }
-
-    #[lang = "eh_personality"]
-    #[no_mangle]
-    extern fn rust_eh_personality(
-        exceptionRecord: *mut EXCEPTION_RECORD,
-        establisherFrame: *mut c_void,
-        contextRecord: *mut CONTEXT,
-        dispatcherContext: *mut DISPATCHER_CONTEXT
-    ) -> EXCEPTION_DISPOSITION
-    {
-        unsafe {
-            __gcc_personality_seh0(exceptionRecord, establisherFrame,
-                                   contextRecord, dispatcherContext)
-        }
-    }
-
-    #[lang = "eh_personality_catch"]
-    #[no_mangle]
-    pub extern fn rust_eh_personality_catch(
-        exceptionRecord: *mut EXCEPTION_RECORD,
-        establisherFrame: *mut c_void,
-        contextRecord: *mut CONTEXT,
-        dispatcherContext: *mut DISPATCHER_CONTEXT
-    ) -> EXCEPTION_DISPOSITION
-    {
-        extern fn inner(
-                _version: c_int,
-                actions: uw::_Unwind_Action,
-                _exception_class: uw::_Unwind_Exception_Class,
-                _ue_header: *mut uw::_Unwind_Exception,
-                _context: *mut uw::_Unwind_Context
-            ) -> uw::_Unwind_Reason_Code
-        {
-            if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
-                uw::_URC_HANDLER_FOUND // catch!
-            }
-            else { // cleanup phase
-                uw::_URC_INSTALL_CONTEXT
+            unsafe {
+                __gcc_personality_v0(state, ue_header, context)
             }
         }
-
-        unsafe {
-            _GCC_specific_handler(exceptionRecord, establisherFrame,
-                                  contextRecord, dispatcherContext,
-                                  inner)
-        }
     }
 }
-
diff --git a/src/libstd/rt/unwind/mod.rs b/src/libstd/rt/unwind/mod.rs
index 60eced014de..59b2e14643d 100644
--- a/src/libstd/rt/unwind/mod.rs
+++ b/src/libstd/rt/unwind/mod.rs
@@ -14,7 +14,7 @@
 //! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and
 //! documents linked from it.
 //! These are also good reads:
-//!     http://theofilos.cs.columbia.edu/blog/2013/09/22/base_abi/
+//!     http://mentorembedded.github.io/cxx-abi/abi-eh.html
 //!     http://monoinfinito.wordpress.com/series/exception-handling-in-c/
 //!     http://www.airs.com/blog/index.php?s=exception+frames
 //!
@@ -76,9 +76,20 @@ use sys_common::mutex::Mutex;
 // The actual unwinding implementation is cfg'd here, and we've got two current
 // implementations. One goes through SEH on Windows and the other goes through
 // libgcc via the libunwind-like API.
-#[cfg(target_env = "msvc")] #[path = "seh.rs"] #[doc(hidden)]
+
+// *-pc-windows-msvc
+#[cfg(all(windows, target_env = "msvc"))]
+#[path = "seh.rs"] #[doc(hidden)]
+pub mod imp;
+
+// x86_64-pc-windows-gnu
+#[cfg(all(windows, target_arch="x86_64", target_env="gnu"))]
+#[path = "seh64_gnu.rs"] #[doc(hidden)]
 pub mod imp;
-#[cfg(not(target_env = "msvc"))] #[path = "gcc.rs"] #[doc(hidden)]
+
+// i686-pc-windows-gnu and all others
+#[cfg(any(unix, all(windows, target_arch="x86", target_env="gnu")))]
+#[path = "gcc.rs"] #[doc(hidden)]
 pub mod imp;
 
 pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: u32);
diff --git a/src/libstd/rt/unwind/seh64_gnu.rs b/src/libstd/rt/unwind/seh64_gnu.rs
new file mode 100644
index 00000000000..6a061a55fc2
--- /dev/null
+++ b/src/libstd/rt/unwind/seh64_gnu.rs
@@ -0,0 +1,227 @@
+// 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.
+
+//! Unwinding implementation of top of native Win64 SEH,
+//! however the unwind handler data (aka LSDA) uses GCC-compatible encoding.
+
+#![allow(bad_style)]
+#![allow(private_no_mangle_fns)]
+
+use prelude::v1::*;
+
+use any::Any;
+use self::EXCEPTION_DISPOSITION::*;
+use rt::dwarf::eh;
+use core::mem;
+use core::ptr;
+use simd;
+use libc::{c_void, c_ulonglong, DWORD, LPVOID};
+type ULONG_PTR = c_ulonglong;
+
+// Define our exception codes:
+// according to http://msdn.microsoft.com/en-us/library/het71c37(v=VS.80).aspx,
+//    [31:30] = 3 (error), 2 (warning), 1 (info), 0 (success)
+//    [29]    = 1 (user-defined)
+//    [28]    = 0 (reserved)
+// we define bits:
+//    [24:27] = type
+//    [0:23]  = magic
+const ETYPE: DWORD = 0b1110_u32 << 28;
+const MAGIC: DWORD = 0x525354; // "RST"
+
+const RUST_PANIC: DWORD  = ETYPE | (1 << 24) | MAGIC;
+
+const EXCEPTION_NONCONTINUABLE: DWORD = 0x1;   // Noncontinuable exception
+const EXCEPTION_UNWINDING: DWORD = 0x2;        // Unwind is in progress
+const EXCEPTION_EXIT_UNWIND: DWORD = 0x4;      // Exit unwind is in progress
+const EXCEPTION_STACK_INVALID: DWORD = 0x8;    // Stack out of limits or unaligned
+const EXCEPTION_NESTED_CALL: DWORD = 0x10;     // Nested exception handler call
+const EXCEPTION_TARGET_UNWIND: DWORD = 0x20;   // Target unwind in progress
+const EXCEPTION_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
+const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING |
+                                EXCEPTION_EXIT_UNWIND |
+                                EXCEPTION_TARGET_UNWIND |
+                                EXCEPTION_COLLIDED_UNWIND;
+
+#[repr(C)]
+pub struct EXCEPTION_RECORD {
+    ExceptionCode: DWORD,
+    ExceptionFlags: DWORD,
+    ExceptionRecord: *const EXCEPTION_RECORD,
+    ExceptionAddress: LPVOID,
+    NumberParameters: DWORD,
+    ExceptionInformation: [ULONG_PTR; 15],
+}
+
+pub type CONTEXT = c_void;
+pub type UNWIND_HISTORY_TABLE = c_void;
+
+#[repr(C)]
+pub struct RUNTIME_FUNCTION {
+    BeginAddress: DWORD,
+    EndAddress: DWORD,
+    UnwindData: DWORD,
+}
+
+#[repr(C)]
+pub struct DISPATCHER_CONTEXT {
+    ControlPc: LPVOID,
+    ImageBase: LPVOID,
+    FunctionEntry: *const RUNTIME_FUNCTION,
+    EstablisherFrame: LPVOID,
+    TargetIp: LPVOID,
+    ContextRecord: *const CONTEXT,
+    LanguageHandler: LPVOID,
+    HandlerData: *const u8,
+    HistoryTable: *const UNWIND_HISTORY_TABLE,
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub enum EXCEPTION_DISPOSITION {
+    ExceptionContinueExecution,
+    ExceptionContinueSearch,
+    ExceptionNestedException,
+    ExceptionCollidedUnwind
+}
+
+// From kernel32.dll
+extern "system" {
+    fn RaiseException(dwExceptionCode: DWORD,
+                      dwExceptionFlags: DWORD,
+                      nNumberOfArguments: DWORD,
+                      lpArguments: *const ULONG_PTR);
+
+    fn RtlUnwindEx(TargetFrame: LPVOID,
+                   TargetIp: LPVOID,
+                   ExceptionRecord: *const EXCEPTION_RECORD,
+                   ReturnValue: LPVOID,
+                   OriginalContext: *const CONTEXT,
+                   HistoryTable: *const UNWIND_HISTORY_TABLE);
+}
+
+#[repr(C)]
+struct PanicData {
+    data: Box<Any + Send + 'static>
+}
+
+pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
+    let panic_ctx = Box::new(PanicData { data: data });
+    let params = [Box::into_raw(panic_ctx) as ULONG_PTR];
+    rtdebug!("panic: ctx={:X}", params[0]);
+    RaiseException(RUST_PANIC,
+                   EXCEPTION_NONCONTINUABLE,
+                   params.len() as DWORD,
+                   &params as *const ULONG_PTR);
+    rtabort!("could not unwind stack");
+}
+
+pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
+    rtdebug!("cleanup: ctx={:X}", ptr as usize);
+    let panic_ctx = Box::from_raw(ptr as *mut PanicData);
+    return panic_ctx.data;
+}
+
+// SEH doesn't support resuming unwinds after calling a landing pad like
+// libunwind does. For this reason, MSVC compiler outlines landing pads into
+// separate functions that can be called directly from the personality function
+// but are nevertheless able to find and modify stack frame of the "parent"
+// function.
+//
+// Since this cannot be done with libdwarf-style landing pads,
+// rust_eh_personality instead catches RUST_PANICs, runs the landing pad, then
+// reraises the exception.
+//
+// Note that it makes certain assumptions about the exception:
+//
+// 1. That RUST_PANIC is non-continuable, so no lower stack frame may choose to
+//    resume execution.
+// 2. That the first parameter of the exception is a pointer to an extra data
+//    area (PanicData).
+// Since these assumptions do not generally hold true for foreign exceptions
+// (system faults, C++ exceptions, etc), we make no attempt to invoke our
+// landing pads (and, thus, destructors!) for anything other than RUST_PANICs.
+// This is considered acceptable, because the behavior of throwing exceptions
+// through a C ABI boundary is undefined.
+
+#[lang = "eh_personality_catch"]
+#[cfg(not(test))]
+unsafe extern fn rust_eh_personality_catch(
+    exceptionRecord: *mut EXCEPTION_RECORD,
+    establisherFrame: LPVOID,
+    contextRecord: *mut CONTEXT,
+    dispatcherContext: *mut DISPATCHER_CONTEXT
+) -> EXCEPTION_DISPOSITION
+{
+    rust_eh_personality(exceptionRecord, establisherFrame,
+                        contextRecord, dispatcherContext)
+}
+
+#[lang = "eh_personality"]
+#[cfg(not(test))]
+unsafe extern fn rust_eh_personality(
+    exceptionRecord: *mut EXCEPTION_RECORD,
+    establisherFrame: LPVOID,
+    contextRecord: *mut CONTEXT,
+    dispatcherContext: *mut DISPATCHER_CONTEXT
+) -> EXCEPTION_DISPOSITION
+{
+    let er = &*exceptionRecord;
+    let dc = &*dispatcherContext;
+    rtdebug!("rust_eh_personality: code={:X}, flags={:X}, frame={:X}, ip={:X}",
+        er.ExceptionCode, er.ExceptionFlags,
+        establisherFrame as usize, dc.ControlPc as usize);
+
+    if er.ExceptionFlags & EXCEPTION_UNWIND == 0 { // we are in the dispatch phase
+        if er.ExceptionCode == RUST_PANIC {
+            if let Some(lpad) = find_landing_pad(dc) {
+                rtdebug!("unwinding to landing pad {:X}", lpad);
+
+                RtlUnwindEx(establisherFrame,
+                            lpad as LPVOID,
+                            exceptionRecord,
+                            er.ExceptionInformation[0] as LPVOID, // pointer to PanicData
+                            contextRecord,
+                            dc.HistoryTable);
+                rtabort!("could not unwind");
+            }
+        }
+    }
+    ExceptionContinueSearch
+}
+
+// The `resume` instruction, found at the end of the landing pads, and whose job
+// is to resume stack unwinding, is typically lowered by LLVM into a call to
+// `_Unwind_Resume` routine.  To avoid confusion with the same symbol exported
+// from libgcc, we redirect it to `rust_eh_unwind_resume`.
+// Since resolution of this symbol is done by the linker, `rust_eh_unwind_resume`
+// must be marked `pub` + `#[no_mangle]`.  (Can we make it a lang item?)
+
+#[lang = "eh_unwind_resume"]
+#[cfg(not(test))]
+unsafe extern fn rust_eh_unwind_resume(panic_ctx: LPVOID) {
+    rtdebug!("rust_eh_unwind_resume: ctx={:X}", panic_ctx as usize);
+    let params = [panic_ctx as ULONG_PTR];
+    RaiseException(RUST_PANIC,
+                   EXCEPTION_NONCONTINUABLE,
+                   params.len() as DWORD,
+                   &params as *const ULONG_PTR);
+    rtabort!("could not resume unwind");
+}
+
+unsafe fn find_landing_pad(dc: &DISPATCHER_CONTEXT) -> Option<usize> {
+    let eh_ctx = eh::EHContext {
+        ip: dc.ControlPc as usize,
+        func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
+        text_start: dc.ImageBase as usize,
+        data_start: 0
+    };
+    eh::find_landing_pad(dc.HandlerData, &eh_ctx)
+}
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 031fda089c8..0fe8d873a75 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -16,38 +16,6 @@ use intrinsics;
 use sync::atomic::{self, Ordering};
 use sys::stdio::Stderr;
 
-/// Dynamically inquire about whether we're running under V.
-/// You should usually not use this unless your test definitely
-/// can't run correctly un-altered. Valgrind is there to help
-/// you notice weirdness in normal, un-doctored code paths!
-pub fn running_on_valgrind() -> bool {
-    return on_valgrind();
-    #[cfg(windows)]
-    fn on_valgrind() -> bool { false }
-
-    #[cfg(unix)]
-    fn on_valgrind() -> bool {
-        use libc::uintptr_t;
-        extern {
-            fn rust_running_on_valgrind() -> uintptr_t;
-        }
-        unsafe { rust_running_on_valgrind() != 0 }
-    }
-}
-
-/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
-/// wired into it; this is a hard limit and requires rebuilding valgrind if you
-/// want to go beyond it. Normally this is not a problem, but in some tests, we
-/// produce a lot of threads casually.  Making lots of threads alone might not
-/// be a problem _either_, except on OSX, the segments produced for new threads
-/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
-/// schedulers fork off a separate thread for polling fsevents on OSX, we get a
-/// perfect storm of creating "too many mappings" for valgrind to handle when
-/// running certain stress tests in the runtime.
-pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
-    (cfg!(target_os="macos")) && running_on_valgrind()
-}
-
 pub fn min_stack() -> usize {
     static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
     match MIN.load(Ordering::SeqCst) {
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index f2c389f9426..79b3dfa67b1 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -69,7 +69,8 @@ pub struct Condvar { inner: Box<StaticCondvar> }
 /// # Examples
 ///
 /// ```
-/// # #![feature(static_condvar)]
+/// #![feature(static_condvar)]
+///
 /// use std::sync::{StaticCondvar, CONDVAR_INIT};
 ///
 /// static CVAR: StaticCondvar = CONDVAR_INIT;
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index 28dc124f033..b87a2756829 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -14,7 +14,8 @@
 //! # Examples
 //!
 //! ```
-//! # #![feature(future)]
+//! #![feature(future)]
+//!
 //! use std::sync::Future;
 //!
 //! // a fake, for now
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 1453c91fd4d..d80d858e7a9 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -1107,7 +1107,7 @@ impl error::Error for TryRecvError {
 mod tests {
     use prelude::v1::*;
 
-    use std::env;
+    use env;
     use super::*;
     use thread;
 
@@ -1655,7 +1655,7 @@ mod tests {
 mod sync_tests {
     use prelude::v1::*;
 
-    use std::env;
+    use env;
     use thread;
     use super::*;
 
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
index a67138742ae..ee1516342ad 100644
--- a/src/libstd/sync/mpsc/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -27,7 +27,8 @@
 //! # Examples
 //!
 //! ```rust
-//! # #![feature(mpsc_select)]
+//! #![feature(mpsc_select)]
+//!
 //! use std::sync::mpsc::channel;
 //!
 //! let (tx1, rx1) = channel();
@@ -124,7 +125,8 @@ impl Select {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(mpsc_select)]
+    /// #![feature(mpsc_select)]
+    ///
     /// use std::sync::mpsc::Select;
     ///
     /// let select = Select::new();
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 41cd11e4c69..4b62434d068 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -138,7 +138,8 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
 /// # Examples
 ///
 /// ```
-/// # #![feature(static_mutex)]
+/// #![feature(static_mutex)]
+///
 /// use std::sync::{StaticMutex, MUTEX_INIT};
 ///
 /// static LOCK: StaticMutex = MUTEX_INIT;
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 4ca2e282f70..40d5af49156 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -81,7 +81,8 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 /// # Examples
 ///
 /// ```
-/// # #![feature(static_rwlock)]
+/// #![feature(static_rwlock)]
+///
 /// use std::sync::{StaticRwLock, RW_LOCK_INIT};
 ///
 /// static LOCK: StaticRwLock = RW_LOCK_INIT;
diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs
index dc9e467a8b1..907df69bfb0 100644
--- a/src/libstd/sync/semaphore.rs
+++ b/src/libstd/sync/semaphore.rs
@@ -25,7 +25,8 @@ use sync::{Mutex, Condvar};
 /// # Examples
 ///
 /// ```
-/// # #![feature(semaphore)]
+/// #![feature(semaphore)]
+///
 /// use std::sync::Semaphore;
 ///
 /// // Create a semaphore that represents 5 resources
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index c8708190a2e..beecb445e8d 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -60,21 +60,22 @@ impl Condvar {
         let r = ffi::gettimeofday(&mut sys_now, ptr::null_mut());
         debug_assert_eq!(r, 0);
 
+        let nsec = dur.extra_nanos() as libc::c_long +
+                   (sys_now.tv_usec * 1000) as libc::c_long;
+        let extra = (nsec / 1_000_000_000) as libc::time_t;
+        let nsec = nsec % 1_000_000_000;
         let seconds = dur.secs() as libc::time_t;
-        let timeout = match sys_now.tv_sec.checked_add(seconds) {
-            Some(sec) => {
-                libc::timespec {
-                    tv_sec: sec,
-                    tv_nsec: dur.extra_nanos() as libc::c_long,
-                }
-            }
-            None => {
-                libc::timespec {
-                    tv_sec: <libc::time_t>::max_value(),
-                    tv_nsec: 1_000_000_000 - 1,
-                }
+
+        let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| {
+            s.checked_add(seconds)
+        }).map(|s| {
+            libc::timespec { tv_sec: s, tv_nsec: nsec }
+        }).unwrap_or_else(|| {
+            libc::timespec {
+                tv_sec: <libc::time_t>::max_value(),
+                tv_nsec: 1_000_000_000 - 1,
             }
-        };
+        });
 
         // And wait!
         let r = ffi::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs
index 63adae17581..06c5261bb42 100644
--- a/src/libstd/sys/unix/ext/process.rs
+++ b/src/libstd/sys/unix/ext/process.rs
@@ -32,6 +32,17 @@ pub trait CommandExt {
     /// the same semantics as the `uid` field.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn gid(&mut self, id: gid_t) -> &mut process::Command;
+
+    /// Create a new session (cf. `setsid(2)`) for the child process. This means that the child is
+    /// the leader of a new process group. The parent process remains the child reaper of the new
+    /// process.
+    ///
+    /// This is not enough to create a daemon process. The *init* process should be the child
+    /// reaper of a daemon. This can be achieved if the parent process exit. Moreover, a daemon
+    /// should not have a controlling terminal. To acheive this, a session leader (the child) must
+    /// spawn another process (the daemon) in the same session.
+    #[unstable(feature = "process_session_leader", reason = "recently added")]
+    fn session_leader(&mut self, on: bool) -> &mut process::Command;
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -45,6 +56,11 @@ impl CommandExt for process::Command {
         self.as_inner_mut().gid = Some(id);
         self
     }
+
+    fn session_leader(&mut self, on: bool) -> &mut process::Command {
+        self.as_inner_mut().session_leader = on;
+        self
+    }
 }
 
 /// Unix-specific extensions to `std::process::ExitStatus`
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index cc78dd4e5ef..2a365cff6cb 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -36,7 +36,7 @@ pub struct Command {
     pub cwd: Option<CString>,
     pub uid: Option<uid_t>,
     pub gid: Option<gid_t>,
-    pub detach: bool, // not currently exposed in std::process
+    pub session_leader: bool,
 }
 
 impl Command {
@@ -48,7 +48,7 @@ impl Command {
             cwd: None,
             uid: None,
             gid: None,
-            detach: false,
+            session_leader: false,
         }
     }
 
@@ -302,7 +302,7 @@ impl Process {
                 fail(&mut output);
             }
         }
-        if cfg.detach {
+        if cfg.session_leader {
             // Don't check the error of setsid because it fails if we're the
             // process leader already. We just forked so it shouldn't return
             // error, but ignore it anyway.
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index 11b375dcce2..9a6d68acb9f 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -107,14 +107,14 @@ pub struct LocalKey<T> {
 #[cfg(not(no_elf_tls))]
 macro_rules! thread_local {
     (static $name:ident: $t:ty = $init:expr) => (
-        static $name: ::std::thread::LocalKey<$t> =
+        static $name: $crate::thread::LocalKey<$t> =
             __thread_local_inner!($t, $init,
                 #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
                                not(target_arch = "aarch64")),
                            thread_local)]);
     );
     (pub static $name:ident: $t:ty = $init:expr) => (
-        pub static $name: ::std::thread::LocalKey<$t> =
+        pub static $name: $crate::thread::LocalKey<$t> =
             __thread_local_inner!($t, $init,
                 #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
                                not(target_arch = "aarch64")),
@@ -128,11 +128,11 @@ macro_rules! thread_local {
 #[cfg(no_elf_tls)]
 macro_rules! thread_local {
     (static $name:ident: $t:ty = $init:expr) => (
-        static $name: ::std::thread::LocalKey<$t> =
+        static $name: $crate::thread::LocalKey<$t> =
             __thread_local_inner!($t, $init, #[]);
     );
     (pub static $name:ident: $t:ty = $init:expr) => (
-        pub static $name: ::std::thread::LocalKey<$t> =
+        pub static $name: $crate::thread::LocalKey<$t> =
             __thread_local_inner!($t, $init, #[]);
     );
 }
@@ -145,11 +145,11 @@ macro_rules! thread_local {
 macro_rules! __thread_local_inner {
     ($t:ty, $init:expr, #[$($attr:meta),*]) => {{
         $(#[$attr])*
-        static __KEY: ::std::thread::__LocalKeyInner<$t> =
-            ::std::thread::__LocalKeyInner::new();
+        static __KEY: $crate::thread::__LocalKeyInner<$t> =
+            $crate::thread::__LocalKeyInner::new();
         fn __init() -> $t { $init }
-        fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY }
-        ::std::thread::LocalKey::new(__getit, __init)
+        fn __getit() -> &'static $crate::thread::__LocalKeyInner<$t> { &__KEY }
+        $crate::thread::LocalKey::new(__getit, __init)
     }}
 }
 
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 3388968c56c..2683f8e5022 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -367,7 +367,8 @@ pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
 /// a join before any relevant stack frames are popped:
 ///
 /// ```rust
-/// # #![feature(scoped)]
+/// #![feature(scoped)]
+///
 /// use std::thread;
 ///
 /// let guard = thread::scoped(move || {
@@ -447,7 +448,8 @@ pub fn panicking() -> bool {
 /// # Examples
 ///
 /// ```
-/// # #![feature(catch_panic)]
+/// #![feature(catch_panic)]
+///
 /// use std::thread;
 ///
 /// let result = thread::catch_panic(|| {
diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs
index c2fad0aa89c..cf2c5db8277 100644
--- a/src/libstd/thread/scoped_tls.rs
+++ b/src/libstd/thread/scoped_tls.rs
@@ -24,7 +24,8 @@
 //! # Examples
 //!
 //! ```
-//! # #![feature(scoped_tls)]
+//! #![feature(scoped_tls)]
+//!
 //! scoped_thread_local!(static FOO: u32);
 //!
 //! // Initially each scoped slot is empty.
@@ -69,11 +70,11 @@ pub struct ScopedKey<T> { inner: fn() -> &'static imp::KeyInner<T> }
 #[allow_internal_unstable]
 macro_rules! scoped_thread_local {
     (static $name:ident: $t:ty) => (
-        static $name: ::std::thread::ScopedKey<$t> =
+        static $name: $crate::thread::ScopedKey<$t> =
             __scoped_thread_local_inner!($t);
     );
     (pub static $name:ident: $t:ty) => (
-        pub static $name: ::std::thread::ScopedKey<$t> =
+        pub static $name: $crate::thread::ScopedKey<$t> =
             __scoped_thread_local_inner!($t);
     );
 }
@@ -86,10 +87,10 @@ macro_rules! scoped_thread_local {
 #[cfg(no_elf_tls)]
 macro_rules! __scoped_thread_local_inner {
     ($t:ty) => {{
-        static _KEY: ::std::thread::__ScopedKeyInner<$t> =
-            ::std::thread::__ScopedKeyInner::new();
-        fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY }
-        ::std::thread::ScopedKey::new(_getit)
+        static _KEY: $crate::thread::__ScopedKeyInner<$t> =
+            $crate::thread::__ScopedKeyInner::new();
+        fn _getit() -> &'static $crate::thread::__ScopedKeyInner<$t> { &_KEY }
+        $crate::thread::ScopedKey::new(_getit)
     }}
 }
 
@@ -108,10 +109,10 @@ macro_rules! __scoped_thread_local_inner {
                            target_os = "openbsd",
                            target_arch = "aarch64")),
                    thread_local)]
-        static _KEY: ::std::thread::__ScopedKeyInner<$t> =
-            ::std::thread::__ScopedKeyInner::new();
-        fn _getit() -> &'static ::std::thread::__ScopedKeyInner<$t> { &_KEY }
-        ::std::thread::ScopedKey::new(_getit)
+        static _KEY: $crate::thread::__ScopedKeyInner<$t> =
+            $crate::thread::__ScopedKeyInner::new();
+        fn _getit() -> &'static $crate::thread::__ScopedKeyInner<$t> { &_KEY }
+        $crate::thread::ScopedKey::new(_getit)
     }}
 }
 
@@ -136,7 +137,8 @@ impl<T> ScopedKey<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(scoped_tls)]
+    /// #![feature(scoped_tls)]
+    ///
     /// scoped_thread_local!(static FOO: u32);
     ///
     /// FOO.set(&100, || {
@@ -189,7 +191,8 @@ impl<T> ScopedKey<T> {
     /// # Examples
     ///
     /// ```no_run
-    /// # #![feature(scoped_tls)]
+    /// #![feature(scoped_tls)]
+    ///
     /// scoped_thread_local!(static FOO: u32);
     ///
     /// FOO.with(|slot| {
@@ -222,7 +225,7 @@ impl<T> ScopedKey<T> {
               no_elf_tls)))]
 #[doc(hidden)]
 mod imp {
-    use std::cell::Cell;
+    use cell::Cell;
 
     pub struct KeyInner<T> { inner: Cell<*mut T> }
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 72711f2ed18..db173d08308 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -87,10 +87,6 @@ pub struct Ident {
 impl Ident {
     /// Construct an identifier with the given name and an empty context:
     pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
-
-    pub fn as_str<'a>(&'a self) -> &'a str {
-        self.name.as_str()
-    }
 }
 
 impl fmt::Debug for Ident {
@@ -108,13 +104,13 @@ impl fmt::Display for Ident {
 impl fmt::Debug for Name {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let Name(nm) = *self;
-        write!(f, "{:?}({})", token::get_name(*self), nm)
+        write!(f, "{}({})", self, nm)
     }
 }
 
 impl fmt::Display for Name {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&token::get_name(*self), f)
+        fmt::Display::fmt(&self.as_str(), f)
     }
 }
 
@@ -134,13 +130,10 @@ impl PartialEq for Ident {
             // one example and its non-hygienic counterpart would be:
             //      syntax::parse::token::Token::mtwt_eq
             //      syntax::ext::tt::macro_parser::token_name_eq
-            panic!("not allowed to compare these idents: {}, {}. \
+            panic!("not allowed to compare these idents: {:?}, {:?}. \
                    Probably related to issue \\#6993", self, other);
         }
     }
-    fn ne(&self, other: &Ident) -> bool {
-        ! self.eq(other)
-    }
 }
 
 /// A SyntaxContext represents a chain of macro-expandings
@@ -166,12 +159,15 @@ pub const ILLEGAL_CTXT : SyntaxContext = 1;
            RustcEncodable, RustcDecodable, Clone, Copy)]
 pub struct Name(pub u32);
 
+impl<T: AsRef<str>> PartialEq<T> for Name {
+    fn eq(&self, other: &T) -> bool {
+        self.as_str() == other.as_ref()
+    }
+}
+
 impl Name {
-    pub fn as_str<'a>(&'a self) -> &'a str {
-        unsafe {
-            // FIXME #12938: can't use copy_lifetime since &str isn't a &T
-            ::std::mem::transmute::<&str,&str>(&token::get_name(*self))
-        }
+    pub fn as_str(&self) -> token::InternedString {
+        token::InternedString::new_from_name(*self)
     }
 
     pub fn usize(&self) -> usize {
@@ -189,7 +185,7 @@ pub type Mrk = u32;
 
 impl Encodable for Ident {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(&token::get_ident(*self))
+        s.emit_str(&self.name.as_str())
     }
 }
 
@@ -1073,7 +1069,7 @@ impl TokenTree {
     pub fn len(&self) -> usize {
         match *self {
             TtToken(_, token::DocComment(name)) => {
-                match doc_comment_style(name.as_str()) {
+                match doc_comment_style(&name.as_str()) {
                     AttrOuter => 2,
                     AttrInner => 3
                 }
@@ -1096,11 +1092,11 @@ impl TokenTree {
                 TtToken(sp, token::Pound)
             }
             (&TtToken(sp, token::DocComment(name)), 1)
-            if doc_comment_style(name.as_str()) == AttrInner => {
+            if doc_comment_style(&name.as_str()) == AttrInner => {
                 TtToken(sp, token::Not)
             }
             (&TtToken(sp, token::DocComment(name)), _) => {
-                let stripped = strip_doc_comment_decoration(name.as_str());
+                let stripped = strip_doc_comment_decoration(&name.as_str());
                 TtDelimited(sp, Rc::new(Delimited {
                     delim: token::Bracket,
                     open_span: sp,
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 6b38762316c..83d3c9c4ec5 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -25,9 +25,7 @@ use std::u32;
 
 pub fn path_name_i(idents: &[Ident]) -> String {
     // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
-    idents.iter().map(|i| {
-        token::get_ident(*i).to_string()
-    }).collect::<Vec<String>>().join("::")
+    idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
 }
 
 pub fn local_def(id: NodeId) -> DefId {
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index f1d748595d6..7476302b2f0 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -322,6 +322,20 @@ enum Destination {
     Raw(Box<Write + Send>),
 }
 
+/// Do not use this for messages that end in `\n` – use `println_maybe_styled` instead. See
+/// `EmitterWriter::print_maybe_styled` for details.
+macro_rules! print_maybe_styled {
+    ($writer: expr, $style: expr, $($arg: tt)*) => {
+        $writer.print_maybe_styled(format_args!($($arg)*), $style, false)
+    }
+}
+
+macro_rules! println_maybe_styled {
+    ($writer: expr, $style: expr, $($arg: tt)*) => {
+        $writer.print_maybe_styled(format_args!($($arg)*), $style, true)
+    }
+}
+
 impl EmitterWriter {
     pub fn stderr(color_config: ColorConfig,
                   registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
@@ -350,8 +364,9 @@ impl EmitterWriter {
     }
 
     fn print_maybe_styled(&mut self,
-                          msg: &str,
-                          color: term::attr::Attr) -> io::Result<()> {
+                          args: fmt::Arguments,
+                          color: term::attr::Attr,
+                          print_newline_at_end: bool) -> io::Result<()> {
         match self.dst {
             Terminal(ref mut t) => {
                 try!(t.attr(color));
@@ -368,17 +383,22 @@ impl EmitterWriter {
                 // once, which still leaves the opportunity for interleaved output
                 // to be miscolored. We assume this is rare enough that we don't
                 // have to worry about it.
-                if msg.ends_with("\n") {
-                    try!(t.write_all(msg[..msg.len()-1].as_bytes()));
-                    try!(t.reset());
-                    try!(t.write_all(b"\n"));
+                try!(t.write_fmt(args));
+                try!(t.reset());
+                if print_newline_at_end {
+                    t.write_all(b"\n")
+                } else {
+                    Ok(())
+                }
+            }
+            Raw(ref mut w) => {
+                try!(w.write_fmt(args));
+                if print_newline_at_end {
+                    w.write_all(b"\n")
                 } else {
-                    try!(t.write_all(msg.as_bytes()));
-                    try!(t.reset());
+                    Ok(())
                 }
-                Ok(())
             }
-            Raw(ref mut w) => w.write_all(msg.as_bytes()),
         }
     }
 
@@ -388,15 +408,14 @@ impl EmitterWriter {
             try!(write!(&mut self.dst, "{} ", topic));
         }
 
-        try!(self.print_maybe_styled(&format!("{}: ", lvl.to_string()),
-                                     term::attr::ForegroundColor(lvl.color())));
-        try!(self.print_maybe_styled(&format!("{}", msg),
-                                     term::attr::Bold));
+        try!(print_maybe_styled!(self, term::attr::ForegroundColor(lvl.color()),
+                                 "{}: ", lvl.to_string()));
+        try!(print_maybe_styled!(self, term::attr::Bold, "{}", msg));
 
         match code {
             Some(code) => {
                 let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
-                try!(self.print_maybe_styled(&format!(" [{}]", code.clone()), style));
+                try!(print_maybe_styled!(self, style, " [{}]", code.clone()));
             }
             None => ()
         }
@@ -627,8 +646,8 @@ impl EmitterWriter {
                     s.pop();
                 }
 
-                try!(self.print_maybe_styled(&format!("{}\n", s),
-                                             term::attr::ForegroundColor(lvl.color())));
+                try!(println_maybe_styled!(self, term::attr::ForegroundColor(lvl.color()),
+                                           "{}", s));
             }
         }
         Ok(())
@@ -700,9 +719,8 @@ impl EmitterWriter {
             }
         }
         s.push('^');
-        s.push('\n');
-        self.print_maybe_styled(&s[..],
-                                term::attr::ForegroundColor(lvl.color()))
+        println_maybe_styled!(self, term::attr::ForegroundColor(lvl.color()),
+                              "{}", s)
     }
 
     fn print_macro_backtrace(&mut self,
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index aee066807f4..48fd05a7550 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -63,7 +63,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
             // Previously used errors.
             Some(&mut ErrorInfo { description: _, use_site: Some(previous_span) }) => {
                 ecx.span_warn(span, &format!(
-                    "diagnostic code {} already used", &token::get_ident(code)
+                    "diagnostic code {} already used", code
                 ));
                 ecx.span_note(previous_span, "previous invocation");
             }
@@ -74,7 +74,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
             // Unregistered errors.
             None => {
                 ecx.span_err(span, &format!(
-                    "used diagnostic code {} not registered", &token::get_ident(code)
+                    "used diagnostic code {} not registered", code
                 ));
             }
         }
@@ -110,7 +110,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
         if !msg.starts_with("\n") || !msg.ends_with("\n") {
             ecx.span_err(span, &format!(
                 "description for error code {} doesn't start and end with a newline",
-                token::get_ident(*code)
+                code
             ));
         }
 
@@ -122,7 +122,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
             ecx.span_err(span, &format!(
                 "description for error code {} contains a line longer than {} characters.\n\
                  if you're inserting a long URL use the footnote style to bypass this check.",
-                token::get_ident(*code), MAX_DESCRIPTION_WIDTH
+                code, MAX_DESCRIPTION_WIDTH
             ));
         }
     });
@@ -134,12 +134,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
         };
         if diagnostics.insert(code.name, info).is_some() {
             ecx.span_err(span, &format!(
-                "diagnostic code {} already registered", &token::get_ident(*code)
+                "diagnostic code {} already registered", code
             ));
         }
     });
-    let sym = Ident::new(token::gensym(&(
-        "__register_diagnostic_".to_string() + &token::get_ident(*code)
+    let sym = Ident::new(token::gensym(&format!(
+        "__register_diagnostic_{}", code
     )));
     MacEager::items(SmallVector::many(vec![
         ecx.item_mod(
@@ -163,7 +163,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             &ast::TtToken(_, token::Ident(ref crate_name, _)),
             // DIAGNOSTICS ident.
             &ast::TtToken(_, token::Ident(ref name, _))
-        ) => (crate_name.as_str(), name),
+        ) => (*&crate_name, name),
         _ => unreachable!()
     };
 
@@ -172,7 +172,10 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
         .ok().expect("unable to determine target arch from $CFG_COMPILER_HOST_TRIPLE");
 
     with_registered_diagnostics(|diagnostics| {
-        if let Err(e) = output_metadata(ecx, &target_triple, crate_name, &diagnostics) {
+        if let Err(e) = output_metadata(ecx,
+                                        &target_triple,
+                                        &crate_name.name.as_str(),
+                                        &diagnostics) {
             ecx.span_bug(span, &format!(
                 "error writing metadata for triple `{}` and crate `{}`, error: {}, cause: {:?}",
                 target_triple, crate_name, e.description(), e.cause()
@@ -187,8 +190,8 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
                 diagnostics.iter().filter_map(|(code, info)| {
                     info.description.map(|description| {
                         ecx.expr_tuple(span, vec![
-                            ecx.expr_str(span, token::get_name(*code)),
-                            ecx.expr_str(span, token::get_name(description))
+                            ecx.expr_str(span, code.as_str()),
+                            ecx.expr_str(span, description.as_str())
                         ])
                     })
                 }).collect();
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 79210cb3260..b91c54ae972 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -629,9 +629,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn expr_field_access(&self, sp: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> {
-        let field_name = token::get_ident(ident);
         let field_span = Span {
-            lo: sp.lo - Pos::from_usize(field_name.len()),
+            lo: sp.lo - Pos::from_usize(ident.name.as_str().len()),
             hi: sp.hi,
             expn_id: sp.expn_id,
         };
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 5d07c36c929..24436c4520d 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -40,7 +40,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
         } else {
             match *e {
                 ast::TtToken(_, token::Ident(ident, _)) => {
-                    res_str.push_str(&token::get_ident(ident))
+                    res_str.push_str(&ident.name.as_str())
                 },
                 _ => {
                     cx.span_err(sp, "concat_idents! requires ident args.");
@@ -49,7 +49,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
             }
         }
     }
-    let res = str_to_ident(&res_str[..]);
+    let res = str_to_ident(&res_str);
 
     let e = P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 99f217a419a..085d9d60937 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -128,7 +128,7 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                 decoder,
                                 cx.ident_of("read_struct"),
                                 vec!(
-                cx.expr_str(trait_span, token::get_ident(substr.type_ident)),
+                cx.expr_str(trait_span, substr.type_ident.name.as_str()),
                 cx.expr_usize(trait_span, nfields),
                 cx.lambda_expr_1(trait_span, result, blkarg)
             ))
@@ -140,10 +140,10 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             let mut variants = Vec::new();
             let rvariant_arg = cx.ident_of("read_enum_variant_arg");
 
-            for (i, &(name, v_span, ref parts)) in fields.iter().enumerate() {
-                variants.push(cx.expr_str(v_span, token::get_ident(name)));
+            for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
+                variants.push(cx.expr_str(v_span, ident.name.as_str()));
 
-                let path = cx.path(trait_span, vec![substr.type_ident, name]);
+                let path = cx.path(trait_span, vec![substr.type_ident, ident]);
                 let decoded = decode_static_fields(cx,
                                                    v_span,
                                                    path,
@@ -175,7 +175,7 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                 decoder,
                                 cx.ident_of("read_enum"),
                                 vec!(
-                cx.expr_str(trait_span, token::get_ident(substr.type_ident)),
+                cx.expr_str(trait_span, substr.type_ident.name.as_str()),
                 cx.lambda_expr_1(trait_span, result, blkarg)
             ))
         }
@@ -211,9 +211,9 @@ fn decode_static_fields<F>(cx: &mut ExtCtxt,
         }
         Named(ref fields) => {
             // use the field's span to get nicer error messages.
-            let fields = fields.iter().enumerate().map(|(i, &(name, span))| {
-                let arg = getarg(cx, span, token::get_ident(name), i);
-                cx.field_imm(span, name, arg)
+            let fields = fields.iter().enumerate().map(|(i, &(ident, span))| {
+                let arg = getarg(cx, span, ident.name.as_str(), i);
+                cx.field_imm(span, ident, arg)
             }).collect();
             cx.expr_struct(trait_span, outer_pat_path, fields)
         }
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 0ef23705f95..ae4d337b9f6 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -186,7 +186,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                     ..
                 }) in fields.iter().enumerate() {
                 let name = match name {
-                    Some(id) => token::get_ident(id),
+                    Some(id) => id.name.as_str(),
                     None => {
                         token::intern_and_get_ident(&format!("_field{}", i))
                     }
@@ -223,7 +223,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                 encoder,
                                 cx.ident_of("emit_struct"),
                                 vec!(
-                cx.expr_str(trait_span, token::get_ident(substr.type_ident)),
+                cx.expr_str(trait_span, substr.type_ident.name.as_str()),
                 cx.expr_usize(trait_span, fields.len()),
                 blk
             ))
@@ -263,7 +263,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             }
 
             let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
-            let name = cx.expr_str(trait_span, token::get_ident(variant.node.name));
+            let name = cx.expr_str(trait_span, variant.node.name.name.as_str());
             let call = cx.expr_method_call(trait_span, blkencoder,
                                            cx.ident_of("emit_enum_variant"),
                                            vec!(name,
@@ -275,7 +275,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                           encoder,
                                           cx.ident_of("emit_enum"),
                                           vec!(
-                cx.expr_str(trait_span, token::get_ident(substr.type_ident)),
+                cx.expr_str(trait_span, substr.type_ident.name.as_str()),
                 blk
             ));
             cx.expr_block(cx.block(trait_span, vec!(me), Some(ret)))
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index e7d242ab703..8f9e0279b29 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -188,6 +188,7 @@ pub use self::SubstructureFields::*;
 use self::StructType::*;
 
 use std::cell::RefCell;
+use std::collections::HashSet;
 use std::vec;
 
 use abi::Abi;
@@ -549,10 +550,20 @@ impl<'a> TraitDef<'a> {
                 .map(|ty_param| ty_param.ident.name)
                 .collect();
 
+            let mut processed_field_types = HashSet::new();
             for field_ty in field_tys {
                 let tys = find_type_parameters(&*field_ty, &ty_param_names);
 
                 for ty in tys {
+                    // if we have already handled this type, skip it
+                    if let ast::TyPath(_, ref p) = ty.node {
+                        if p.segments.len() == 1
+                            && ty_param_names.contains(&p.segments[0].identifier.name)
+                            || processed_field_types.contains(&p.segments) {
+                            continue;
+                        };
+                        processed_field_types.insert(p.segments.clone());
+                    }
                     let mut bounds: Vec<_> = self.additional_bounds.iter().map(|p| {
                         cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
                     }).collect();
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index dbde963bda9..3a478884c6a 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -59,7 +59,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     // build fmt.debug_struct(<name>).field(<fieldname>, &<fieldval>)....build()
     // or fmt.debug_tuple(<name>).field(&<fieldval>)....build()
     // based on the "shape".
-    let name = match *substr.fields {
+    let ident = match *substr.fields {
         Struct(_) => substr.type_ident,
         EnumMatching(_, v, _) => v.node.name,
         EnumNonMatchingCollapsed(..) | StaticStruct(..) | StaticEnum(..) => {
@@ -69,7 +69,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
 
     // We want to make sure we have the expn_id set so that we can use unstable methods
     let span = Span { expn_id: cx.backtrace(), .. span };
-    let name = cx.expr_lit(span, ast::Lit_::LitStr(token::get_ident(name),
+    let name = cx.expr_lit(span, ast::Lit_::LitStr(ident.name.as_str(),
                                                    ast::StrStyle::CookedStr));
     let mut expr = substr.nonself_args[0].clone();
 
@@ -102,7 +102,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
 
                 for field in fields {
                     let name = cx.expr_lit(field.span, ast::Lit_::LitStr(
-                            token::get_ident(field.name.clone().unwrap()),
+                            field.name.unwrap().name.as_str(),
                             ast::StrStyle::CookedStr));
 
                     // Use double indirection to make sure this works for unsized types
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 286dc91299f..6e49b190f7c 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -545,14 +545,13 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
                 // let compilation continue
                 return None;
             }
-            let extname = pth.segments[0].identifier;
-            let extnamestr = token::get_ident(extname);
-            match fld.cx.syntax_env.find(&extname.name) {
+            let extname = pth.segments[0].identifier.name;
+            match fld.cx.syntax_env.find(&extname) {
                 None => {
                     fld.cx.span_err(
                         pth.span,
                         &format!("macro undefined: '{}!'",
-                                &extnamestr));
+                                &extname));
 
                     // let compilation continue
                     None
@@ -562,7 +561,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
                         fld.cx.bt_push(ExpnInfo {
                                 call_site: span,
                                 callee: NameAndSpan {
-                                    name: extnamestr.to_string(),
+                                    name: extname.to_string(),
                                     format: MacroBang,
                                     span: exp_span,
                                     allow_internal_unstable: allow_internal_unstable,
@@ -589,7 +588,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
                                 fld.cx.span_err(
                                     pth.span,
                                     &format!("non-expression macro in expression position: {}",
-                                            &extnamestr[..]
+                                            extname
                                             ));
                                 return None;
                             }
@@ -600,7 +599,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
                         fld.cx.span_err(
                             pth.span,
                             &format!("'{}' is not a tt-style macro",
-                                    &extnamestr));
+                                    extname));
                         None
                     }
                 }
@@ -712,19 +711,18 @@ pub fn expand_item_mac(it: P<ast::Item>,
             node: MacInvocTT(ref pth, ref tts, _),
             ..
         }) => {
-            (pth.segments[0].identifier, pth.span, (*tts).clone())
+            (pth.segments[0].identifier.name, pth.span, (*tts).clone())
         }
         _ => fld.cx.span_bug(it.span, "invalid item macro invocation")
     };
 
-    let extnamestr = token::get_ident(extname);
     let fm = fresh_mark();
     let items = {
-        let expanded = match fld.cx.syntax_env.find(&extname.name) {
+        let expanded = match fld.cx.syntax_env.find(&extname) {
             None => {
                 fld.cx.span_err(path_span,
                                 &format!("macro undefined: '{}!'",
-                                        extnamestr));
+                                        extname));
                 // let compilation continue
                 return SmallVector::zero();
             }
@@ -735,14 +733,14 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         fld.cx
                             .span_err(path_span,
                                       &format!("macro {}! expects no ident argument, given '{}'",
-                                               extnamestr,
-                                               token::get_ident(it.ident)));
+                                               extname,
+                                               it.ident));
                         return SmallVector::zero();
                     }
                     fld.cx.bt_push(ExpnInfo {
                         call_site: it.span,
                         callee: NameAndSpan {
-                            name: extnamestr.to_string(),
+                            name: extname.to_string(),
                             format: MacroBang,
                             span: span,
                             allow_internal_unstable: allow_internal_unstable,
@@ -756,13 +754,13 @@ pub fn expand_item_mac(it: P<ast::Item>,
                     if it.ident.name == parse::token::special_idents::invalid.name {
                         fld.cx.span_err(path_span,
                                         &format!("macro {}! expects an ident argument",
-                                                &extnamestr));
+                                                extname));
                         return SmallVector::zero();
                     }
                     fld.cx.bt_push(ExpnInfo {
                         call_site: it.span,
                         callee: NameAndSpan {
-                            name: extnamestr.to_string(),
+                            name: extname.to_string(),
                             format: MacroBang,
                             span: span,
                             allow_internal_unstable: allow_internal_unstable,
@@ -783,7 +781,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                     fld.cx.bt_push(ExpnInfo {
                         call_site: it.span,
                         callee: NameAndSpan {
-                            name: extnamestr.to_string(),
+                            name: extname.to_string(),
                             format: MacroBang,
                             span: None,
                             // `macro_rules!` doesn't directly allow
@@ -828,7 +826,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                 _ => {
                     fld.cx.span_err(it.span,
                                     &format!("{}! is not legal in item position",
-                                            &extnamestr));
+                                            extname));
                     return SmallVector::zero();
                 }
             }
@@ -847,7 +845,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
         None => {
             fld.cx.span_err(path_span,
                             &format!("non-item macro in item position: {}",
-                                    &extnamestr));
+                                    extname));
             return SmallVector::zero();
         }
     };
@@ -1096,13 +1094,12 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
             fld.cx.span_err(pth.span, "expected macro name without module separators");
             return DummyResult::raw_pat(span);
         }
-        let extname = pth.segments[0].identifier;
-        let extnamestr = token::get_ident(extname);
-        let marked_after = match fld.cx.syntax_env.find(&extname.name) {
+        let extname = pth.segments[0].identifier.name;
+        let marked_after = match fld.cx.syntax_env.find(&extname) {
             None => {
                 fld.cx.span_err(pth.span,
                                 &format!("macro undefined: '{}!'",
-                                        extnamestr));
+                                        extname));
                 // let compilation continue
                 return DummyResult::raw_pat(span);
             }
@@ -1112,7 +1109,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
                     fld.cx.bt_push(ExpnInfo {
                         call_site: span,
                         callee: NameAndSpan {
-                            name: extnamestr.to_string(),
+                            name: extname.to_string(),
                             format: MacroBang,
                             span: tt_span,
                             allow_internal_unstable: allow_internal_unstable,
@@ -1132,7 +1129,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
                                 pth.span,
                                 &format!(
                                     "non-pattern macro in pattern position: {}",
-                                    &extnamestr
+                                    extname
                                     )
                             );
                             return DummyResult::raw_pat(span);
@@ -1145,7 +1142,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
                 _ => {
                     fld.cx.span_err(span,
                                     &format!("{}! is not legal in pattern position",
-                                            &extnamestr));
+                                            extname));
                     return DummyResult::raw_pat(span);
                 }
             }
@@ -2121,8 +2118,7 @@ mod tests {
                         = varref.segments.iter().map(|s| s.identifier)
                         .collect();
                     println!("varref #{}: {:?}, resolves to {}",idx, varref_idents, varref_name);
-                    let string = token::get_ident(final_varref_ident);
-                    println!("varref's first segment's string: \"{}\"", &string[..]);
+                    println!("varref's first segment's string: \"{}\"", final_varref_ident);
                     println!("binding #{}: {}, resolves to {}",
                              binding_idx, bindings[binding_idx], binding_name);
                     mtwt::with_sctable(|x| mtwt::display_sctable(x));
@@ -2174,11 +2170,7 @@ foo_module!();
         // find the xx binding
         let bindings = crate_bindings(&cr);
         let cxbinds: Vec<&ast::Ident> =
-            bindings.iter().filter(|b| {
-                let ident = token::get_ident(**b);
-                let string = &ident[..];
-                "xx" == string
-            }).collect();
+            bindings.iter().filter(|b| b.name == "xx").collect();
         let cxbinds: &[&ast::Ident] = &cxbinds[..];
         let cxbind = match (cxbinds.len(), cxbinds.get(0)) {
             (1, Some(b)) => *b,
@@ -2190,7 +2182,7 @@ foo_module!();
         // the xx binding should bind all of the xx varrefs:
         for (idx,v) in varrefs.iter().filter(|p| {
             p.segments.len() == 1
-            && "xx" == &*token::get_ident(p.segments[0].identifier)
+            && p.segments[0].identifier.name == "xx"
         }).enumerate() {
             if mtwt::resolve(v.segments[0].identifier) != resolved_binding {
                 println!("uh oh, xx binding didn't match xx varref:");
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 5b972b464c9..5a2b9c0eea4 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -121,8 +121,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                     return None;
                 }
             };
-            let interned_name = token::get_ident(ident);
-            let name = &interned_name[..];
+            let name: &str = &ident.name.as_str();
 
             panictry!(p.expect(&token::Eq));
             let e = p.parse_expr();
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 82c249d2585..b8168297190 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -407,7 +407,7 @@ fn id_ext(str: &str) -> ast::Ident {
 
 // Lift an ident to the expr that evaluates to that ident.
 fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P<ast::Expr> {
-    let e_str = cx.expr_str(sp, token::get_ident(ident));
+    let e_str = cx.expr_str(sp, ident.name.as_str());
     cx.expr_method_call(sp,
                         cx.expr_ident(sp, id_ext("ext_cx")),
                         id_ext("ident_of"),
@@ -416,7 +416,7 @@ fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P<ast::Expr> {
 
 // Lift a name to the expr that evaluates to that name
 fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P<ast::Expr> {
-    let e_str = cx.expr_str(sp, token::get_ident(ident));
+    let e_str = cx.expr_str(sp, ident.name.as_str());
     cx.expr_method_call(sp,
                         cx.expr_ident(sp, id_ext("ext_cx")),
                         id_ext("name_of"),
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 22517dc5f1b..8da36b2c1e1 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -76,7 +76,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     base::check_zero_tts(cx, sp, tts, "module_path!");
     let string = cx.mod_path()
                    .iter()
-                   .map(|x| token::get_ident(*x).to_string())
+                   .map(|x| x.to_string())
                    .collect::<Vec<String>>()
                    .join("::");
     base::MacEager::expr(cx.expr_str(
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 5b3887e76b4..4556bd5f8e5 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -223,11 +223,10 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
                         *idx += 1;
                     }
                     Occupied(..) => {
-                        let string = token::get_ident(bind_name);
                         panic!(p_s.span_diagnostic
                            .span_fatal(sp,
                                        &format!("duplicated bind name: {}",
-                                               &string)))
+                                               bind_name)))
                     }
                 }
             }
@@ -460,9 +459,7 @@ pub fn parse(sess: &ParseSess,
                 let nts = bb_eis.iter().map(|ei| {
                     match ei.top_elts.get_tt(ei.idx) {
                       TtToken(_, MatchNt(bind, name, _, _)) => {
-                        (format!("{} ('{}')",
-                                token::get_ident(name),
-                                token::get_ident(bind))).to_string()
+                        format!("{} ('{}')", name, bind)
                       }
                       _ => panic!()
                     } }).collect::<Vec<String>>().join(" or ");
@@ -484,11 +481,10 @@ pub fn parse(sess: &ParseSess,
 
                 let mut ei = bb_eis.pop().unwrap();
                 match ei.top_elts.get_tt(ei.idx) {
-                  TtToken(span, MatchNt(_, name, _, _)) => {
-                    let name_string = token::get_ident(name);
+                  TtToken(span, MatchNt(_, ident, _, _)) => {
                     let match_cur = ei.match_cur;
                     (&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal(
-                        parse_nt(&mut rust_parser, span, &name_string))));
+                        parse_nt(&mut rust_parser, span, &ident.name.as_str()))));
                     ei.idx += 1;
                     ei.match_cur += 1;
                   }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index e29e0ab54d1..adc88c329a3 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -56,10 +56,9 @@ impl<'a> ParserAnyMacro<'a> {
             let span = parser.span;
             parser.span_err(span, &msg[..]);
 
-            let name = token::get_ident(self.macro_ident);
             let msg = format!("caused by the macro expansion here; the usage \
                                of `{}` is likely invalid in this context",
-                               name);
+                               self.macro_ident);
             parser.span_note(self.site_span, &msg[..]);
         }
     }
@@ -154,7 +153,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                           -> Box<MacResult+'cx> {
     if cx.trace_macros() {
         println!("{}! {{ {} }}",
-                 token::get_ident(name),
+                 name,
                  print::pprust::tts_to_string(arg));
     }
 
@@ -326,7 +325,7 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
             TtToken(sp, MatchNt(ref name, ref frag_spec, _, _)) => {
                 // ii. If T is a simple NT, look ahead to the next token T' in
                 // M. If T' is in the set FOLLOW(NT), continue. Else; reject.
-                if can_be_followed_by_any(frag_spec.as_str()) {
+                if can_be_followed_by_any(&frag_spec.name.as_str()) {
                     continue
                 } else {
                     let next_token = match tokens.peek() {
@@ -340,13 +339,13 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
                             // possibility that the sequence occurred
                             // zero times (in which case we need to
                             // look at the token that follows the
-                            // sequence, which may itself a sequence,
+                            // sequence, which may itself be a sequence,
                             // and so on).
                             cx.span_err(sp,
                                         &format!("`${0}:{1}` is followed by a \
                                                   sequence repetition, which is not \
                                                   allowed for `{1}` fragments",
-                                                 name.as_str(), frag_spec.as_str())
+                                                 name, frag_spec)
                                         );
                             Eof
                         },
@@ -359,7 +358,7 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
                     let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
 
                     // If T' is in the set FOLLOW(NT), continue. Else, reject.
-                    match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
+                    match (&next_token, is_in_follow(cx, &next_token, &frag_spec.name.as_str())) {
                         (_, Err(msg)) => {
                             cx.span_err(sp, &msg);
                             continue
@@ -369,7 +368,7 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
                         (next, Ok(false)) => {
                             cx.span_err(sp, &format!("`${0}:{1}` is followed by `{2}`, which \
                                                       is not allowed for `{1}` fragments",
-                                                     name.as_str(), frag_spec.as_str(),
+                                                     name, frag_spec,
                                                      token_to_string(next)));
                             continue
                         },
@@ -495,14 +494,14 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> {
             "pat" => {
                 match *tok {
                     FatArrow | Comma | Eq => Ok(true),
-                    Ident(i, _) if i.as_str() == "if" || i.as_str() == "in" => Ok(true),
+                    Ident(i, _) if i.name == "if" || i.name == "in" => Ok(true),
                     _ => Ok(false)
                 }
             },
             "path" | "ty" => {
                 match *tok {
                     Comma | FatArrow | Colon | Eq | Gt | Semi => Ok(true),
-                    Ident(i, _) if i.as_str() == "as" => Ok(true),
+                    Ident(i, _) if i.name == "as" => Ok(true),
                     _ => Ok(false)
                 }
             },
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 368a9f0c27e..0ca755c97b1 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -140,11 +140,9 @@ impl Add for LockstepIterSize {
                 LisContradiction(_) => other,
                 LisConstraint(r_len, _) if l_len == r_len => self.clone(),
                 LisConstraint(r_len, r_id) => {
-                    let l_n = token::get_ident(l_id.clone());
-                    let r_n = token::get_ident(r_id);
                     LisContradiction(format!("inconsistent lockstep iteration: \
-                                              '{:?}' has {} items, but '{:?}' has {}",
-                                              l_n, l_len, r_n, r_len).to_string())
+                                              '{}' has {} items, but '{}' has {}",
+                                              l_id, l_len, r_id, r_len))
                 }
             },
         }
@@ -308,8 +306,8 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                             MatchedSeq(..) => {
                                 panic!(r.sp_diag.span_fatal(
                                     r.cur_span, /* blame the macro writer */
-                                    &format!("variable '{:?}' is still repeating at this depth",
-                                            token::get_ident(ident))));
+                                    &format!("variable '{}' is still repeating at this depth",
+                                            ident)));
                             }
                         }
                     }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index c3338f02ee4..945e457a77b 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -163,8 +163,12 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
 
     // Allows the definition recursive static items.
     ("static_recursion", "1.3.0", Active),
-// Allows default type parameters to influence type inference.
-    ("default_type_parameter_fallback", "1.3.0", Active)
+
+    // Allows default type parameters to influence type inference.
+    ("default_type_parameter_fallback", "1.3.0", Active),
+
+    // Allows associated type defaults
+    ("associated_type_defaults", "1.2.0", Active),
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -582,7 +586,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
     }
 
     fn visit_name(&mut self, sp: Span, name: ast::Name) {
-        if !token::get_name(name).is_ascii() {
+        if !name.as_str().is_ascii() {
             self.gate_feature("non_ascii_idents", sp,
                               "non-ascii idents are not fully supported.");
         }
@@ -762,6 +766,10 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                     self.gate_feature("const_fn", ti.span, "const fn is unstable");
                 }
             }
+            ast::TypeTraitItem(_, Some(_)) => {
+                self.gate_feature("associated_type_defaults", ti.span,
+                                  "associated type defaults are unstable");
+            }
             _ => {}
         }
         visit::walk_trait_item(self, ti);
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 621335ecd97..019a8404dfb 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -694,7 +694,7 @@ impl<'a> StringReader<'a> {
             accum_int *= 16;
             accum_int += c.to_digit(16).unwrap_or_else(|| {
                 self.err_span_char(self.last_pos, self.pos,
-                              "illegal character in numeric character escape", c);
+                              "invalid character in numeric character escape", c);
 
                 valid = false;
                 0
@@ -714,7 +714,7 @@ impl<'a> StringReader<'a> {
             Some(_) => valid,
             None => {
                 let last_bpos = self.last_pos;
-                self.err_span_(start_bpos, last_bpos, "illegal numeric character escape");
+                self.err_span_(start_bpos, last_bpos, "invalid numeric character escape");
                 false
             }
         }
@@ -846,7 +846,7 @@ impl<'a> StringReader<'a> {
                                      "unterminated unicode escape (needed a `}`)");
                 } else {
                     self.err_span_char(self.last_pos, self.pos,
-                                   "illegal character in unicode escape", c);
+                                   "invalid character in unicode escape", c);
                 }
                 valid = false;
                 0
@@ -862,7 +862,7 @@ impl<'a> StringReader<'a> {
         }
 
         if valid && (char::from_u32(accum_int).is_none() || count == 0) {
-            self.err_span_(start_bpos, self.last_pos, "illegal unicode character escape");
+            self.err_span_(start_bpos, self.last_pos, "invalid unicode character escape");
             valid = false;
         }
 
@@ -1138,8 +1138,8 @@ impl<'a> StringReader<'a> {
                 let last_bpos = self.last_pos;
                 let curr_char = self.curr.unwrap();
                 self.fatal_span_char(start_bpos, last_bpos,
-                                "only `#` is allowed in raw string delimitation; \
-                                 found illegal character",
+                                "found invalid character; \
+                                 only `#` is allowed in raw string delimitation",
                                 curr_char);
             }
             self.bump();
@@ -1323,8 +1323,8 @@ impl<'a> StringReader<'a> {
             let last_pos = self.last_pos;
             let ch = self.curr.unwrap();
             self.fatal_span_char(start_bpos, last_pos,
-                            "only `#` is allowed in raw string delimitation; \
-                             found illegal character",
+                            "found invalid character; \
+                             only `#` is allowed in raw string delimitation",
                             ch);
         }
         self.bump();
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 34a63fc92fe..c5a73601d89 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -15,6 +15,7 @@ use codemap::{self, Span, CodeMap, FileMap};
 use diagnostic::{SpanHandler, Handler, Auto, FatalError};
 use parse::attr::ParserAttr;
 use parse::parser::Parser;
+use parse::token::InternedString;
 use ptr::P;
 use str::char_at;
 
@@ -439,17 +440,17 @@ fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
 fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>,
                       sd: &SpanHandler, sp: Span) -> ast::Lit_ {
     debug!("filtered_float_lit: {}, {:?}", data, suffix);
-    match suffix {
+    match suffix.as_ref().map(|s| &**s) {
         Some("f32") => ast::LitFloat(data, ast::TyF32),
         Some("f64") => ast::LitFloat(data, ast::TyF64),
         Some(suf) => {
             if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) {
                 // if it looks like a width, lets try to be helpful.
-                sd.span_err(sp, &*format!("illegal width `{}` for float literal, \
-                                          valid widths are 32 and 64", &suf[1..]));
+                sd.span_err(sp, &*format!("invalid width `{}` for float literal", &suf[1..]));
+                sd.fileline_help(sp, "valid widths are 32 and 64");
             } else {
-                sd.span_err(sp, &*format!("illegal suffix `{}` for float literal, \
-                                          valid suffixes are `f32` and `f64`", suf));
+                sd.span_err(sp, &*format!("invalid suffix `{}` for float literal", suf));
+                sd.fileline_help(sp, "valid suffixes are `f32` and `f64`");
             }
 
             ast::LitFloatUnsuffixed(data)
@@ -457,12 +458,13 @@ fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>,
         None => ast::LitFloatUnsuffixed(data)
     }
 }
-pub fn float_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
+pub fn float_lit(s: &str, suffix: Option<InternedString>,
+                 sd: &SpanHandler, sp: Span) -> ast::Lit_ {
     debug!("float_lit: {:?}, {:?}", s, suffix);
     // FIXME #2252: bounds checking float literals is deferred until trans
     let s = s.chars().filter(|&c| c != '_').collect::<String>();
-    let data = token::intern_and_get_ident(&*s);
-    filtered_float_lit(data, suffix, sd, sp)
+    let data = token::intern_and_get_ident(&s);
+    filtered_float_lit(data, suffix.as_ref().map(|s| &**s), sd, sp)
 }
 
 /// Parse a string representing a byte literal into its final form. Similar to `char_lit`
@@ -557,7 +559,11 @@ pub fn binary_lit(lit: &str) -> Rc<Vec<u8>> {
     Rc::new(res)
 }
 
-pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
+pub fn integer_lit(s: &str,
+                   suffix: Option<InternedString>,
+                   sd: &SpanHandler,
+                   sp: Span)
+                   -> ast::Lit_ {
     // s can only be ascii, byte indexing is fine
 
     let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
@@ -579,8 +585,8 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
     }
 
     // 1f64 and 2f32 etc. are valid float literals.
-    match suffix {
-        Some(suf) if looks_like_width_suffix(&['f'], suf) => {
+    if let Some(ref suf) = suffix {
+        if looks_like_width_suffix(&['f'], suf) {
             match base {
                 16 => sd.span_err(sp, "hexadecimal float literal is not supported"),
                 8 => sd.span_err(sp, "octal float literal is not supported"),
@@ -588,18 +594,17 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
                 _ => ()
             }
             let ident = token::intern_and_get_ident(&*s);
-            return filtered_float_lit(ident, suffix, sd, sp)
+            return filtered_float_lit(ident, Some(&**suf), sd, sp)
         }
-        _ => {}
     }
 
     if base != 10 {
         s = &s[2..];
     }
 
-    if let Some(suf) = suffix {
+    if let Some(ref suf) = suffix {
         if suf.is_empty() { sd.span_bug(sp, "found empty literal suffix in Some")}
-        ty = match suf {
+        ty = match &**suf {
             "isize" => ast::SignedIntLit(ast::TyIs, ast::Plus),
             "i8"  => ast::SignedIntLit(ast::TyI8, ast::Plus),
             "i16" => ast::SignedIntLit(ast::TyI16, ast::Plus),
@@ -614,11 +619,11 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
                 // i<digits> and u<digits> look like widths, so lets
                 // give an error message along those lines
                 if looks_like_width_suffix(&['i', 'u'], suf) {
-                    sd.span_err(sp, &*format!("illegal width `{}` for integer literal; \
-                                              valid widths are 8, 16, 32 and 64",
+                    sd.span_err(sp, &*format!("invalid width `{}` for integer literal",
                                               &suf[1..]));
+                    sd.fileline_help(sp, "valid widths are 8, 16, 32 and 64");
                 } else {
-                    sd.span_err(sp, &*format!("illegal suffix `{}` for numeric literal", suf));
+                    sd.span_err(sp, &*format!("invalid suffix `{}` for numeric literal", suf));
                     sd.fileline_help(sp, "the suffix must be one of the integral types \
                                       (`u32`, `isize`, etc)");
                 }
@@ -739,8 +744,8 @@ mod tests {
                 Some(&ast::TtToken(_, token::Ident(name_zip, token::Plain))),
                 Some(&ast::TtDelimited(_, ref macro_delimed)),
             )
-            if name_macro_rules.as_str() == "macro_rules"
-            && name_zip.as_str() == "zip" => {
+            if name_macro_rules.name == "macro_rules"
+            && name_zip.name == "zip" => {
                 let tts = &macro_delimed.tts[..];
                 match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
                     (
@@ -755,10 +760,10 @@ mod tests {
                             (
                                 2,
                                 Some(&ast::TtToken(_, token::Dollar)),
-                                Some(&ast::TtToken(_, token::Ident(name, token::Plain))),
+                                Some(&ast::TtToken(_, token::Ident(ident, token::Plain))),
                             )
                             if first_delimed.delim == token::Paren
-                            && name.as_str() == "a" => {},
+                            && ident.name == "a" => {},
                             _ => panic!("value 3: {:?}", **first_delimed),
                         }
                         let tts = &second_delimed.tts[..];
@@ -766,10 +771,10 @@ mod tests {
                             (
                                 2,
                                 Some(&ast::TtToken(_, token::Dollar)),
-                                Some(&ast::TtToken(_, token::Ident(name, token::Plain))),
+                                Some(&ast::TtToken(_, token::Ident(ident, token::Plain))),
                             )
                             if second_delimed.delim == token::Paren
-                            && name.as_str() == "a" => {},
+                            && ident.name == "a" => {},
                             _ => panic!("value 4: {:?}", **second_delimed),
                         }
                     },
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 00d9b7f4ea6..bc355f70fb3 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -13,11 +13,8 @@
 //!
 //! Obsolete syntax that becomes too hard to parse can be removed.
 
-use ast::{Expr, ExprTup};
 use codemap::Span;
 use parse::parser;
-use parse::token;
-use ptr::P;
 
 /// The specific types of unsupported syntax
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
@@ -29,17 +26,12 @@ pub enum ObsoleteSyntax {
 pub trait ParserObsoleteMethods {
     /// Reports an obsolete syntax non-fatal error.
     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
-    /// Reports an obsolete syntax non-fatal error, and returns
-    /// a placeholder expression
-    fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr>;
     fn report(&mut self,
               sp: Span,
               kind: ObsoleteSyntax,
               kind_str: &str,
               desc: &str,
               error: bool);
-    fn is_obsolete_ident(&mut self, ident: &str) -> bool;
-    fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
 }
 
 impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
@@ -61,13 +53,6 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
         self.report(sp, kind, kind_str, desc, error);
     }
 
-    /// Reports an obsolete syntax non-fatal error, and returns
-    /// a placeholder expression
-    fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr> {
-        self.obsolete(sp, kind);
-        self.mk_expr(sp.lo, sp.hi, ExprTup(vec![]))
-    }
-
     fn report(&mut self,
               sp: Span,
               kind: ObsoleteSyntax,
@@ -89,22 +74,4 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
             self.obsolete_set.insert(kind);
         }
     }
-
-    fn is_obsolete_ident(&mut self, ident: &str) -> bool {
-        match self.token {
-            token::Ident(sid, _) => {
-                token::get_ident(sid) == ident
-            }
-            _ => false
-        }
-    }
-
-    fn eat_obsolete_ident(&mut self, ident: &str) -> bool {
-        if self.is_obsolete_ident(ident) {
-            panictry!(self.bump());
-            true
-        } else {
-            false
-        }
-    }
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 80a10b2463f..e7ab9a73c0f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -288,7 +288,7 @@ impl TokenType {
         match *self {
             TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)),
             TokenType::Operator => "an operator".to_string(),
-            TokenType::Keyword(kw) => format!("`{}`", token::get_name(kw.to_name())),
+            TokenType::Keyword(kw) => format!("`{}`", kw.to_name()),
         }
     }
 }
@@ -681,7 +681,7 @@ impl<'a> Parser<'a> {
                 if text.is_empty() {
                     self.span_bug(sp, "found empty literal suffix in Some")
                 }
-                self.span_err(sp, &*format!("{} with a suffix is illegal", kind));
+                self.span_err(sp, &*format!("{} with a suffix is invalid", kind));
             }
         }
     }
@@ -1023,7 +1023,7 @@ impl<'a> Parser<'a> {
     }
 
     pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
-        token::get_ident(id)
+        id.name.as_str()
     }
 
     /// Is the current token one of the keywords that signals a bare function
@@ -1498,20 +1498,20 @@ impl<'a> Parser<'a> {
             }
             token::Literal(lit, suf) => {
                 let (suffix_illegal, out) = match lit {
-                    token::Byte(i) => (true, LitByte(parse::byte_lit(i.as_str()).0)),
-                    token::Char(i) => (true, LitChar(parse::char_lit(i.as_str()).0)),
+                    token::Byte(i) => (true, LitByte(parse::byte_lit(&i.as_str()).0)),
+                    token::Char(i) => (true, LitChar(parse::char_lit(&i.as_str()).0)),
 
                     // there are some valid suffixes for integer and
                     // float literals, so all the handling is done
                     // internally.
                     token::Integer(s) => {
-                        (false, parse::integer_lit(s.as_str(),
+                        (false, parse::integer_lit(&s.as_str(),
                                                    suf.as_ref().map(|s| s.as_str()),
                                                    &self.sess.span_diagnostic,
                                                    self.last_span))
                     }
                     token::Float(s) => {
-                        (false, parse::float_lit(s.as_str(),
+                        (false, parse::float_lit(&s.as_str(),
                                                  suf.as_ref().map(|s| s.as_str()),
                                                   &self.sess.span_diagnostic,
                                                  self.last_span))
@@ -1519,20 +1519,20 @@ impl<'a> Parser<'a> {
 
                     token::Str_(s) => {
                         (true,
-                         LitStr(token::intern_and_get_ident(&parse::str_lit(s.as_str())),
+                         LitStr(token::intern_and_get_ident(&parse::str_lit(&s.as_str())),
                                 ast::CookedStr))
                     }
                     token::StrRaw(s, n) => {
                         (true,
                          LitStr(
-                            token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())),
+                            token::intern_and_get_ident(&parse::raw_str_lit(&s.as_str())),
                             ast::RawStr(n)))
                     }
                     token::Binary(i) =>
-                        (true, LitBinary(parse::binary_lit(i.as_str()))),
+                        (true, LitBinary(parse::binary_lit(&i.as_str()))),
                     token::BinaryRaw(i, _) =>
                         (true,
-                         LitBinary(Rc::new(i.as_str().as_bytes().iter().cloned().collect()))),
+                         LitBinary(Rc::new(i.to_string().into_bytes()))),
                 };
 
                 if suffix_illegal {
@@ -2448,7 +2448,7 @@ impl<'a> Parser<'a> {
             match self.token {
                 token::SubstNt(name, _) =>
                     return Err(self.fatal(&format!("unknown macro variable `{}`",
-                                       token::get_ident(name)))),
+                                       name))),
                 _ => {}
             }
         }
@@ -4610,7 +4610,7 @@ impl<'a> Parser<'a> {
             None
         };
 
-        if try!(self.eat(&token::DotDot) ){
+        if opt_trait.is_some() && try!(self.eat(&token::DotDot) ){
             if generics.is_parameterized() {
                 self.span_err(impl_span, "default trait implementations are not \
                                           allowed to have generics");
@@ -4736,7 +4736,7 @@ impl<'a> Parser<'a> {
             if fields.is_empty() {
                 return Err(self.fatal(&format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))));
+                    class_name)));
             }
 
             try!(self.bump());
@@ -4775,7 +4775,7 @@ impl<'a> Parser<'a> {
             if fields.is_empty() {
                 return Err(self.fatal(&format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))));
+                    class_name)));
             }
 
             generics.where_clause = try!(self.parse_where_clause());
@@ -4920,8 +4920,7 @@ impl<'a> Parser<'a> {
     /// Returns either a path to a module, or .
     pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -> ModulePath
     {
-        let mod_string = token::get_ident(id);
-        let mod_name = mod_string.to_string();
+        let mod_name = id.to_string();
         let default_path_str = format!("{}.rs", mod_name);
         let secondary_path_str = format!("{}/mod.rs", mod_name);
         let default_path = dir_path.join(&default_path_str);
@@ -5009,7 +5008,7 @@ impl<'a> Parser<'a> {
 
         self.eval_src_mod_from_path(path,
                                     owns_directory,
-                                    token::get_ident(id).to_string(),
+                                    id.to_string(),
                                     id_sp)
     }
 
@@ -5213,7 +5212,7 @@ impl<'a> Parser<'a> {
                     self.span_err(start_span,
                         &format!("unit-like struct variant should be written \
                                  without braces, as `{},`",
-                                token::get_ident(ident)));
+                                ident));
                 }
                 kind = StructVariantKind(struct_def);
             } else if self.check(&token::OpenDelim(token::Paren)) {
@@ -5281,17 +5280,16 @@ impl<'a> Parser<'a> {
                 let sp = self.span;
                 self.expect_no_suffix(sp, "ABI spec", suf);
                 try!(self.bump());
-                let the_string = s.as_str();
-                match abi::lookup(the_string) {
+                match abi::lookup(&s.as_str()) {
                     Some(abi) => Ok(Some(abi)),
                     None => {
                         let last_span = self.last_span;
                         self.span_err(
                             last_span,
-                            &format!("illegal ABI: expected one of [{}], \
+                            &format!("invalid ABI: expected one of [{}], \
                                      found `{}`",
                                     abi::all_names().join(", "),
-                                    the_string));
+                                    s));
                         Ok(None)
                     }
                 }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 832fec40199..bd479255438 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -647,6 +647,12 @@ impl InternedString {
             string: string,
         }
     }
+
+    #[inline]
+    pub fn new_from_name(name: ast::Name) -> InternedString {
+        let interner = get_ident_interner();
+        InternedString::new_from_rc_str(interner.get(name))
+    }
 }
 
 impl Deref for InternedString {
@@ -678,7 +684,7 @@ impl<'a> PartialEq<&'a str> for InternedString {
     }
 }
 
-impl<'a> PartialEq<InternedString > for &'a str {
+impl<'a> PartialEq<InternedString> for &'a str {
     #[inline(always)]
     fn eq(&self, other: &InternedString) -> bool {
         PartialEq::eq(*self, &other.string[..])
@@ -691,7 +697,7 @@ impl<'a> PartialEq<InternedString > for &'a str {
 
 impl Decodable for InternedString {
     fn decode<D: Decoder>(d: &mut D) -> Result<InternedString, D::Error> {
-        Ok(get_name(get_ident_interner().intern(&try!(d.read_str())[..])))
+        Ok(intern(try!(d.read_str()).as_ref()).as_str())
     }
 }
 
@@ -701,25 +707,11 @@ impl Encodable for InternedString {
     }
 }
 
-/// Returns the string contents of a name, using the thread-local interner.
-#[inline]
-pub fn get_name(name: ast::Name) -> InternedString {
-    let interner = get_ident_interner();
-    InternedString::new_from_rc_str(interner.get(name))
-}
-
-/// Returns the string contents of an identifier, using the thread-local
-/// interner.
-#[inline]
-pub fn get_ident(ident: ast::Ident) -> InternedString {
-    get_name(ident.name)
-}
-
 /// Interns and returns the string contents of an identifier, using the
 /// thread-local interner.
 #[inline]
 pub fn intern_and_get_ident(s: &str) -> InternedString {
-    get_name(intern(s))
+    intern(s).as_str()
 }
 
 /// Maps a string to its interned representation.
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 448857389da..6cfe85bc37e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -251,40 +251,40 @@ pub fn token_to_string(tok: &Token) -> String {
         /* Literals */
         token::Literal(lit, suf) => {
             let mut out = match lit {
-                token::Byte(b)           => format!("b'{}'", b.as_str()),
-                token::Char(c)           => format!("'{}'", c.as_str()),
-                token::Float(c)          => c.as_str().to_string(),
-                token::Integer(c)        => c.as_str().to_string(),
-                token::Str_(s)           => format!("\"{}\"", s.as_str()),
+                token::Byte(b)           => format!("b'{}'", b),
+                token::Char(c)           => format!("'{}'", c),
+                token::Float(c)          => c.to_string(),
+                token::Integer(c)        => c.to_string(),
+                token::Str_(s)           => format!("\"{}\"", s),
                 token::StrRaw(s, n)      => format!("r{delim}\"{string}\"{delim}",
                                                     delim=repeat("#", n),
-                                                    string=s.as_str()),
-                token::Binary(v)         => format!("b\"{}\"", v.as_str()),
+                                                    string=s),
+                token::Binary(v)         => format!("b\"{}\"", v),
                 token::BinaryRaw(s, n)   => format!("br{delim}\"{string}\"{delim}",
                                                     delim=repeat("#", n),
-                                                    string=s.as_str()),
+                                                    string=s),
             };
 
             if let Some(s) = suf {
-                out.push_str(s.as_str())
+                out.push_str(&s.as_str())
             }
 
             out
         }
 
         /* Name components */
-        token::Ident(s, _)          => token::get_ident(s).to_string(),
-        token::Lifetime(s)          => format!("{}", token::get_ident(s)),
+        token::Ident(s, _)          => s.to_string(),
+        token::Lifetime(s)          => s.to_string(),
         token::Underscore           => "_".to_string(),
 
         /* Other */
-        token::DocComment(s)        => s.as_str().to_string(),
+        token::DocComment(s)        => s.to_string(),
         token::SubstNt(s, _)        => format!("${}", s),
         token::MatchNt(s, t, _, _)  => format!("${}:{}", s, t),
         token::Eof                  => "<eof>".to_string(),
         token::Whitespace           => " ".to_string(),
         token::Comment              => "/* */".to_string(),
-        token::Shebang(s)           => format!("/* shebang: {}*/", s.as_str()),
+        token::Shebang(s)           => format!("/* shebang: {}*/", s),
 
         token::SpecialVarNt(var)    => format!("${}", var.as_str()),
 
@@ -819,7 +819,7 @@ impl<'a> State<'a> {
                 try!(self.head(&visibility_qualified(item.vis,
                                                      "extern crate")));
                 if let Some(p) = *optional_path {
-                    let val = token::get_name(p);
+                    let val = p.as_str();
                     if val.contains("-") {
                         try!(self.print_string(&val, ast::CookedStr));
                     } else {
@@ -2009,7 +2009,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
-        try!(word(&mut self.s, &token::get_ident(ident)));
+        try!(word(&mut self.s, &ident.name.as_str()));
         self.ann.post(self, NodeIdent(&ident))
     }
 
@@ -2018,7 +2018,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
-        try!(word(&mut self.s, &token::get_name(name)));
+        try!(word(&mut self.s, &name.as_str()));
         self.ann.post(self, NodeName(&name))
     }
 
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 36550586531..9787f2537c6 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -160,8 +160,7 @@ impl fold::Folder for PreludeInjector {
                     style: ast::AttrOuter,
                     value: P(ast::MetaItem {
                         span: self.span,
-                        node: ast::MetaWord(token::get_name(
-                                special_idents::prelude_import.name)),
+                        node: ast::MetaWord(special_idents::prelude_import.name.as_str()),
                     }),
                     is_sugared_doc: false,
                 },
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 22c12fdf3de..194b6c8e3e2 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -41,7 +41,6 @@
 #![feature(fnbox)]
 #![feature(iter_cmp)]
 #![feature(libc)]
-#![feature(rt)]
 #![feature(rustc_private)]
 #![feature(set_stdio)]
 #![feature(staged_api)]
@@ -879,13 +878,7 @@ fn get_concurrency() -> usize {
                 _ => panic!("RUST_TEST_THREADS is `{}`, should be a positive integer.", s)
             }
         }
-        Err(..) => {
-            if std::rt::util::limit_thread_creation_due_to_osx_and_valgrind() {
-                1
-            } else {
-                num_cpus()
-            }
-        }
+        Err(..) => num_cpus(),
     };
 
     #[cfg(windows)]
diff --git a/src/rt/msvc/inttypes.h b/src/rt/msvc/inttypes.h
deleted file mode 100644
index 4b3828a2162..00000000000
--- a/src/rt/msvc/inttypes.h
+++ /dev/null
@@ -1,305 +0,0 @@
-// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
-// 
-//  Copyright (c) 2006 Alexander Chemeris
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//   1. Redistributions of source code must retain the above copyright notice,
-//      this list of conditions and the following disclaimer.
-// 
-//   2. Redistributions in binary form must reproduce the above copyright
-//      notice, this list of conditions and the following disclaimer in the
-//      documentation and/or other materials provided with the distribution.
-// 
-//   3. The name of the author may be used to endorse or promote products
-//      derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_INTTYPES_H_ // [
-#define _MSC_INTTYPES_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#include "stdint.h"
-
-// 7.8 Format conversion of integer types
-
-typedef struct {
-   intmax_t quot;
-   intmax_t rem;
-} imaxdiv_t;
-
-// 7.8.1 Macros for format specifiers
-
-#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198
-
-// The fprintf macros for signed integers are:
-#define PRId8       "d"
-#define PRIi8       "i"
-#define PRIdLEAST8  "d"
-#define PRIiLEAST8  "i"
-#define PRIdFAST8   "d"
-#define PRIiFAST8   "i"
-
-#define PRId16       "hd"
-#define PRIi16       "hi"
-#define PRIdLEAST16  "hd"
-#define PRIiLEAST16  "hi"
-#define PRIdFAST16   "hd"
-#define PRIiFAST16   "hi"
-
-#define PRId32       "I32d"
-#define PRIi32       "I32i"
-#define PRIdLEAST32  "I32d"
-#define PRIiLEAST32  "I32i"
-#define PRIdFAST32   "I32d"
-#define PRIiFAST32   "I32i"
-
-#define PRId64       "I64d"
-#define PRIi64       "I64i"
-#define PRIdLEAST64  "I64d"
-#define PRIiLEAST64  "I64i"
-#define PRIdFAST64   "I64d"
-#define PRIiFAST64   "I64i"
-
-#define PRIdMAX     "I64d"
-#define PRIiMAX     "I64i"
-
-#define PRIdPTR     "Id"
-#define PRIiPTR     "Ii"
-
-// The fprintf macros for unsigned integers are:
-#define PRIo8       "o"
-#define PRIu8       "u"
-#define PRIx8       "x"
-#define PRIX8       "X"
-#define PRIoLEAST8  "o"
-#define PRIuLEAST8  "u"
-#define PRIxLEAST8  "x"
-#define PRIXLEAST8  "X"
-#define PRIoFAST8   "o"
-#define PRIuFAST8   "u"
-#define PRIxFAST8   "x"
-#define PRIXFAST8   "X"
-
-#define PRIo16       "ho"
-#define PRIu16       "hu"
-#define PRIx16       "hx"
-#define PRIX16       "hX"
-#define PRIoLEAST16  "ho"
-#define PRIuLEAST16  "hu"
-#define PRIxLEAST16  "hx"
-#define PRIXLEAST16  "hX"
-#define PRIoFAST16   "ho"
-#define PRIuFAST16   "hu"
-#define PRIxFAST16   "hx"
-#define PRIXFAST16   "hX"
-
-#define PRIo32       "I32o"
-#define PRIu32       "I32u"
-#define PRIx32       "I32x"
-#define PRIX32       "I32X"
-#define PRIoLEAST32  "I32o"
-#define PRIuLEAST32  "I32u"
-#define PRIxLEAST32  "I32x"
-#define PRIXLEAST32  "I32X"
-#define PRIoFAST32   "I32o"
-#define PRIuFAST32   "I32u"
-#define PRIxFAST32   "I32x"
-#define PRIXFAST32   "I32X"
-
-#define PRIo64       "I64o"
-#define PRIu64       "I64u"
-#define PRIx64       "I64x"
-#define PRIX64       "I64X"
-#define PRIoLEAST64  "I64o"
-#define PRIuLEAST64  "I64u"
-#define PRIxLEAST64  "I64x"
-#define PRIXLEAST64  "I64X"
-#define PRIoFAST64   "I64o"
-#define PRIuFAST64   "I64u"
-#define PRIxFAST64   "I64x"
-#define PRIXFAST64   "I64X"
-
-#define PRIoMAX     "I64o"
-#define PRIuMAX     "I64u"
-#define PRIxMAX     "I64x"
-#define PRIXMAX     "I64X"
-
-#define PRIoPTR     "Io"
-#define PRIuPTR     "Iu"
-#define PRIxPTR     "Ix"
-#define PRIXPTR     "IX"
-
-// The fscanf macros for signed integers are:
-#define SCNd8       "d"
-#define SCNi8       "i"
-#define SCNdLEAST8  "d"
-#define SCNiLEAST8  "i"
-#define SCNdFAST8   "d"
-#define SCNiFAST8   "i"
-
-#define SCNd16       "hd"
-#define SCNi16       "hi"
-#define SCNdLEAST16  "hd"
-#define SCNiLEAST16  "hi"
-#define SCNdFAST16   "hd"
-#define SCNiFAST16   "hi"
-
-#define SCNd32       "ld"
-#define SCNi32       "li"
-#define SCNdLEAST32  "ld"
-#define SCNiLEAST32  "li"
-#define SCNdFAST32   "ld"
-#define SCNiFAST32   "li"
-
-#define SCNd64       "I64d"
-#define SCNi64       "I64i"
-#define SCNdLEAST64  "I64d"
-#define SCNiLEAST64  "I64i"
-#define SCNdFAST64   "I64d"
-#define SCNiFAST64   "I64i"
-
-#define SCNdMAX     "I64d"
-#define SCNiMAX     "I64i"
-
-#ifdef _WIN64 // [
-#  define SCNdPTR     "I64d"
-#  define SCNiPTR     "I64i"
-#else  // _WIN64 ][
-#  define SCNdPTR     "ld"
-#  define SCNiPTR     "li"
-#endif  // _WIN64 ]
-
-// The fscanf macros for unsigned integers are:
-#define SCNo8       "o"
-#define SCNu8       "u"
-#define SCNx8       "x"
-#define SCNX8       "X"
-#define SCNoLEAST8  "o"
-#define SCNuLEAST8  "u"
-#define SCNxLEAST8  "x"
-#define SCNXLEAST8  "X"
-#define SCNoFAST8   "o"
-#define SCNuFAST8   "u"
-#define SCNxFAST8   "x"
-#define SCNXFAST8   "X"
-
-#define SCNo16       "ho"
-#define SCNu16       "hu"
-#define SCNx16       "hx"
-#define SCNX16       "hX"
-#define SCNoLEAST16  "ho"
-#define SCNuLEAST16  "hu"
-#define SCNxLEAST16  "hx"
-#define SCNXLEAST16  "hX"
-#define SCNoFAST16   "ho"
-#define SCNuFAST16   "hu"
-#define SCNxFAST16   "hx"
-#define SCNXFAST16   "hX"
-
-#define SCNo32       "lo"
-#define SCNu32       "lu"
-#define SCNx32       "lx"
-#define SCNX32       "lX"
-#define SCNoLEAST32  "lo"
-#define SCNuLEAST32  "lu"
-#define SCNxLEAST32  "lx"
-#define SCNXLEAST32  "lX"
-#define SCNoFAST32   "lo"
-#define SCNuFAST32   "lu"
-#define SCNxFAST32   "lx"
-#define SCNXFAST32   "lX"
-
-#define SCNo64       "I64o"
-#define SCNu64       "I64u"
-#define SCNx64       "I64x"
-#define SCNX64       "I64X"
-#define SCNoLEAST64  "I64o"
-#define SCNuLEAST64  "I64u"
-#define SCNxLEAST64  "I64x"
-#define SCNXLEAST64  "I64X"
-#define SCNoFAST64   "I64o"
-#define SCNuFAST64   "I64u"
-#define SCNxFAST64   "I64x"
-#define SCNXFAST64   "I64X"
-
-#define SCNoMAX     "I64o"
-#define SCNuMAX     "I64u"
-#define SCNxMAX     "I64x"
-#define SCNXMAX     "I64X"
-
-#ifdef _WIN64 // [
-#  define SCNoPTR     "I64o"
-#  define SCNuPTR     "I64u"
-#  define SCNxPTR     "I64x"
-#  define SCNXPTR     "I64X"
-#else  // _WIN64 ][
-#  define SCNoPTR     "lo"
-#  define SCNuPTR     "lu"
-#  define SCNxPTR     "lx"
-#  define SCNXPTR     "lX"
-#endif  // _WIN64 ]
-
-#endif // __STDC_FORMAT_MACROS ]
-
-// 7.8.2 Functions for greatest-width integer types
-
-// 7.8.2.1 The imaxabs function
-#define imaxabs _abs64
-
-// 7.8.2.2 The imaxdiv function
-
-// This is modified version of div() function from Microsoft's div.c found
-// in %MSVC.NET%\crt\src\div.c
-#ifdef STATIC_IMAXDIV // [
-static
-#else // STATIC_IMAXDIV ][
-_inline
-#endif // STATIC_IMAXDIV ]
-imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
-{
-   imaxdiv_t result;
-
-   result.quot = numer / denom;
-   result.rem = numer % denom;
-
-   if (numer < 0 && result.rem > 0) {
-      // did division wrong; must fix up
-      ++result.quot;
-      result.rem -= denom;
-   }
-
-   return result;
-}
-
-// 7.8.2.3 The strtoimax and strtoumax functions
-#define strtoimax _strtoi64
-#define strtoumax _strtoui64
-
-// 7.8.2.4 The wcstoimax and wcstoumax functions
-#define wcstoimax _wcstoi64
-#define wcstoumax _wcstoui64
-
-
-#endif // _MSC_INTTYPES_H_ ]
diff --git a/src/rt/msvc/stdint.h b/src/rt/msvc/stdint.h
deleted file mode 100644
index d02608a5972..00000000000
--- a/src/rt/msvc/stdint.h
+++ /dev/null
@@ -1,247 +0,0 @@
-// ISO C9x  compliant stdint.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
-// 
-//  Copyright (c) 2006-2008 Alexander Chemeris
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//   1. Redistributions of source code must retain the above copyright notice,
-//      this list of conditions and the following disclaimer.
-// 
-//   2. Redistributions in binary form must reproduce the above copyright
-//      notice, this list of conditions and the following disclaimer in the
-//      documentation and/or other materials provided with the distribution.
-// 
-//   3. The name of the author may be used to endorse or promote products
-//      derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_STDINT_H_ // [
-#define _MSC_STDINT_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#include <limits.h>
-
-// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
-// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
-// or compiler give many errors like this:
-//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#ifdef __cplusplus
-extern "C" {
-#endif
-#  include <wchar.h>
-#ifdef __cplusplus
-}
-#endif
-
-// Define _W64 macros to mark types changing their size, like intptr_t.
-#ifndef _W64
-#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
-#     define _W64 __w64
-#  else
-#     define _W64
-#  endif
-#endif
-
-
-// 7.18.1 Integer types
-
-// 7.18.1.1 Exact-width integer types
-
-// Visual Studio 6 and Embedded Visual C++ 4 doesn't
-// realize that, e.g. char has the same size as __int8
-// so we give up on __intX for them.
-#if (_MSC_VER < 1300)
-   typedef signed char       int8_t;
-   typedef signed short      int16_t;
-   typedef signed int        int32_t;
-   typedef unsigned char     uint8_t;
-   typedef unsigned short    uint16_t;
-   typedef unsigned int      uint32_t;
-#else
-   typedef signed __int8     int8_t;
-   typedef signed __int16    int16_t;
-   typedef signed __int32    int32_t;
-   typedef unsigned __int8   uint8_t;
-   typedef unsigned __int16  uint16_t;
-   typedef unsigned __int32  uint32_t;
-#endif
-typedef signed __int64       int64_t;
-typedef unsigned __int64     uint64_t;
-
-
-// 7.18.1.2 Minimum-width integer types
-typedef int8_t    int_least8_t;
-typedef int16_t   int_least16_t;
-typedef int32_t   int_least32_t;
-typedef int64_t   int_least64_t;
-typedef uint8_t   uint_least8_t;
-typedef uint16_t  uint_least16_t;
-typedef uint32_t  uint_least32_t;
-typedef uint64_t  uint_least64_t;
-
-// 7.18.1.3 Fastest minimum-width integer types
-typedef int8_t    int_fast8_t;
-typedef int16_t   int_fast16_t;
-typedef int32_t   int_fast32_t;
-typedef int64_t   int_fast64_t;
-typedef uint8_t   uint_fast8_t;
-typedef uint16_t  uint_fast16_t;
-typedef uint32_t  uint_fast32_t;
-typedef uint64_t  uint_fast64_t;
-
-// 7.18.1.4 Integer types capable of holding object pointers
-#ifdef _WIN64 // [
-   typedef signed __int64    intptr_t;
-   typedef unsigned __int64  uintptr_t;
-#else // _WIN64 ][
-   typedef _W64 signed int   intptr_t;
-   typedef _W64 unsigned int uintptr_t;
-#endif // _WIN64 ]
-
-// 7.18.1.5 Greatest-width integer types
-typedef int64_t   intmax_t;
-typedef uint64_t  uintmax_t;
-
-
-// 7.18.2 Limits of specified-width integer types
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
-
-// 7.18.2.1 Limits of exact-width integer types
-#define INT8_MIN     ((int8_t)_I8_MIN)
-#define INT8_MAX     _I8_MAX
-#define INT16_MIN    ((int16_t)_I16_MIN)
-#define INT16_MAX    _I16_MAX
-#define INT32_MIN    ((int32_t)_I32_MIN)
-#define INT32_MAX    _I32_MAX
-#define INT64_MIN    ((int64_t)_I64_MIN)
-#define INT64_MAX    _I64_MAX
-#define UINT8_MAX    _UI8_MAX
-#define UINT16_MAX   _UI16_MAX
-#define UINT32_MAX   _UI32_MAX
-#define UINT64_MAX   _UI64_MAX
-
-// 7.18.2.2 Limits of minimum-width integer types
-#define INT_LEAST8_MIN    INT8_MIN
-#define INT_LEAST8_MAX    INT8_MAX
-#define INT_LEAST16_MIN   INT16_MIN
-#define INT_LEAST16_MAX   INT16_MAX
-#define INT_LEAST32_MIN   INT32_MIN
-#define INT_LEAST32_MAX   INT32_MAX
-#define INT_LEAST64_MIN   INT64_MIN
-#define INT_LEAST64_MAX   INT64_MAX
-#define UINT_LEAST8_MAX   UINT8_MAX
-#define UINT_LEAST16_MAX  UINT16_MAX
-#define UINT_LEAST32_MAX  UINT32_MAX
-#define UINT_LEAST64_MAX  UINT64_MAX
-
-// 7.18.2.3 Limits of fastest minimum-width integer types
-#define INT_FAST8_MIN    INT8_MIN
-#define INT_FAST8_MAX    INT8_MAX
-#define INT_FAST16_MIN   INT16_MIN
-#define INT_FAST16_MAX   INT16_MAX
-#define INT_FAST32_MIN   INT32_MIN
-#define INT_FAST32_MAX   INT32_MAX
-#define INT_FAST64_MIN   INT64_MIN
-#define INT_FAST64_MAX   INT64_MAX
-#define UINT_FAST8_MAX   UINT8_MAX
-#define UINT_FAST16_MAX  UINT16_MAX
-#define UINT_FAST32_MAX  UINT32_MAX
-#define UINT_FAST64_MAX  UINT64_MAX
-
-// 7.18.2.4 Limits of integer types capable of holding object pointers
-#ifdef _WIN64 // [
-#  define INTPTR_MIN   INT64_MIN
-#  define INTPTR_MAX   INT64_MAX
-#  define UINTPTR_MAX  UINT64_MAX
-#else // _WIN64 ][
-#  define INTPTR_MIN   INT32_MIN
-#  define INTPTR_MAX   INT32_MAX
-#  define UINTPTR_MAX  UINT32_MAX
-#endif // _WIN64 ]
-
-// 7.18.2.5 Limits of greatest-width integer types
-#define INTMAX_MIN   INT64_MIN
-#define INTMAX_MAX   INT64_MAX
-#define UINTMAX_MAX  UINT64_MAX
-
-// 7.18.3 Limits of other integer types
-
-#ifdef _WIN64 // [
-#  define PTRDIFF_MIN  _I64_MIN
-#  define PTRDIFF_MAX  _I64_MAX
-#else  // _WIN64 ][
-#  define PTRDIFF_MIN  _I32_MIN
-#  define PTRDIFF_MAX  _I32_MAX
-#endif  // _WIN64 ]
-
-#define SIG_ATOMIC_MIN  INT_MIN
-#define SIG_ATOMIC_MAX  INT_MAX
-
-#ifndef SIZE_MAX // [
-#  ifdef _WIN64 // [
-#     define SIZE_MAX  _UI64_MAX
-#  else // _WIN64 ][
-#     define SIZE_MAX  _UI32_MAX
-#  endif // _WIN64 ]
-#endif // SIZE_MAX ]
-
-// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
-#ifndef WCHAR_MIN // [
-#  define WCHAR_MIN  0
-#endif  // WCHAR_MIN ]
-#ifndef WCHAR_MAX // [
-#  define WCHAR_MAX  _UI16_MAX
-#endif  // WCHAR_MAX ]
-
-#define WINT_MIN  0
-#define WINT_MAX  _UI16_MAX
-
-#endif // __STDC_LIMIT_MACROS ]
-
-
-// 7.18.4 Limits of other integer types
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val)  val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val)  val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-#define INTMAX_C   INT64_C
-#define UINTMAX_C  UINT64_C
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-
-#endif // _MSC_STDINT_H_ ]
diff --git a/src/rt/msvc/typeof.h b/src/rt/msvc/typeof.h
deleted file mode 100644
index 7de08af314a..00000000000
--- a/src/rt/msvc/typeof.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// This piece of magic brought to you by:
-//     http://www.nedproductions.biz/blog/
-//     implementing-typeof-in-microsofts-c-compiler 
-
-#ifndef MSVC_TYPEOF_H
-#define MSVC_TYPEOF_H
-
-#if defined(_MSC_VER) && _MSC_VER>=1400
-namespace msvc_typeof_impl {
-	/* This is a fusion of Igor Chesnokov's method (http://rsdn.ru/forum/src/1094305.aspx)
-	and Steven Watanabe's method (http://lists.boost.org/Archives/boost/2006/12/115006.php)
-
-	How it works:
-	C++ allows template type inference for templated function parameters but nothing else.
-	What we do is to pass the expression sent to typeof() into the templated function vartypeID()
-	as its parameter, thus extracting its type. The big problem traditionally now is how to get
-	that type out of the vartypeID() instance, and here's how we do it:
-		1. unique_type_id() returns a monotonically increasing integer for every unique type
-		   passed to it during this compilation unit. It also specialises an instance of
-		   msvc_extract_type<unique_type_id, type>::id2type_impl<true>.
-		2. vartypeID() returns a sized<unique_type_id> for the type where
-		   sizeof(sized<unique_type_id>)==unique_type_id. We vector through sized as a means
-		   of returning the unique_type_id at compile time rather than runtime.
-		3. msvc_extract_type<unique_type_id> then extracts the type by using a bug in MSVC to
-		   reselect the specialised child type (id2type_impl<true>) from within the specialisation
-		   of itself originally performed by the above instance of unique_type_id. This bug works
-		   because when MSVC calculated the signature of the specialised
-		   msvc_extract_type<unique_type_id, type>::id2type_impl<true>, it does not include the
-		   value of type in the signature of id2type_impl<true>. Therefore when we reselect
-		   msvc_extract_type<unique_type_id>::id2type_impl<true> it erroneously returns the one
-		   already in its list of instantiated types rather than correctly generating a newly
-		   specialised msvc_extract_type<unique_type_id, msvc_extract_type_default_param>::id2type_impl<true>
-
-	This bug allows the impossible and gives us a working typeof() in MSVC. Hopefully Microsoft
-	won't fix this bug until they implement a native typeof.
-	*/
-
-	struct msvc_extract_type_default_param {};
-	template<int ID, typename T = msvc_extract_type_default_param> struct msvc_extract_type;
-
-	template<int ID> struct msvc_extract_type<ID, msvc_extract_type_default_param>
-	{
-		template<bool> struct id2type_impl; 
-
-		typedef id2type_impl<true> id2type; 
-	};
-
-	template<int ID, typename T> struct msvc_extract_type : msvc_extract_type<ID, msvc_extract_type_default_param> 
-	{ 
-		template<> struct id2type_impl<true> //VC8.0 specific bugfeature 
-		{ 
-			typedef T type; 
-		}; 
-		template<bool> struct id2type_impl; 
-
-		typedef id2type_impl<true> id2type; 
-	}; 
-
-
-	template<int N> class CCounter;
-
-	// TUnused is required to force compiler to recompile CCountOf class
-	template<typename TUnused, int NTested = 0> struct CCountOf
-	{
-		enum
-		{
-			__if_exists(CCounter<NTested>) { count = CCountOf<TUnused, NTested + 1>::count }
-			__if_not_exists(CCounter<NTested>) { count = NTested }
-		};
-	};
-
-	template<class TTypeReg, class TUnused, int NValue> struct CProvideCounterValue { enum { value = NValue }; };
-
-	// type_id
-	#define unique_type_id(type) \
-		(CProvideCounterValue< \
-			/*register TYPE--ID*/ typename msvc_extract_type<CCountOf<type >::count, type>::id2type, \
-			/*increment compile-time Counter*/ CCounter<CCountOf<type >::count>, \
-			/*pass value of Counter*/CCountOf<type >::count \
-		 >::value)
-
-	// Lets type_id() be > than 0
-	class __Increment_type_id { enum { value = unique_type_id(__Increment_type_id) }; };
-
-	// vartypeID() returns a type with sizeof(type_id)
-	template<int NSize>	class sized { char m_pad[NSize]; };
-	template<typename T> typename sized<unique_type_id(T)> vartypeID(T&);
-	template<typename T> typename sized<unique_type_id(const T)> vartypeID(const T&);
-	template<typename T> typename sized<unique_type_id(volatile  T)> vartypeID(volatile T&);
-	template<typename T> typename sized<unique_type_id(const volatile T)> vartypeID(const volatile T&);
-}
-
-#define typeof(expression) msvc_typeof_impl::msvc_extract_type<sizeof(msvc_typeof_impl::vartypeID(expression))>::id2type::type
-#endif
-
-#endif
diff --git a/src/rt/rust_builtin.c b/src/rt/rust_builtin.c
index 76a3debef59..9a5eaad4243 100644
--- a/src/rt/rust_builtin.c
+++ b/src/rt/rust_builtin.c
@@ -34,10 +34,6 @@
 #endif
 #endif
 
-/* Foreign builtins. */
-//include valgrind.h after stdint.h so that uintptr_t is defined for msys2 w64
-#include "valgrind/valgrind.h"
-
 char*
 rust_list_dir_val(struct dirent* entry_ptr) {
     return entry_ptr->d_name;
@@ -118,11 +114,6 @@ rust_get_num_cpus() {
     return get_num_cpus();
 }
 
-uintptr_t
-rust_running_on_valgrind() {
-    return RUNNING_ON_VALGRIND;
-}
-
 #if defined(__DragonFly__)
 #include <errno.h>
 // In DragonFly __error() is an inline function and as such
diff --git a/src/rt/valgrind/memcheck.h b/src/rt/valgrind/memcheck.h
deleted file mode 100644
index ee72707d319..00000000000
--- a/src/rt/valgrind/memcheck.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
-   ----------------------------------------------------------------
-
-   Notice that the following BSD-style license applies to this one
-   file (memcheck.h) only.  The rest of Valgrind is licensed under the
-   terms of the GNU General Public License, version 2, unless
-   otherwise indicated.  See the COPYING file in the source
-   distribution for details.
-
-   ----------------------------------------------------------------
-
-   This file is part of MemCheck, a heavyweight Valgrind tool for
-   detecting memory errors.
-
-   Copyright (C) 2000-2013 Julian Seward.  All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-   1. Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-   2. The origin of this software must not be misrepresented; you must 
-      not claim that you wrote the original software.  If you use this 
-      software in a product, an acknowledgment in the product 
-      documentation would be appreciated but is not required.
-
-   3. Altered source versions must be plainly marked as such, and must
-      not be misrepresented as being the original software.
-
-   4. The name of the author may not be used to endorse or promote 
-      products derived from this software without specific prior written 
-      permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-   ----------------------------------------------------------------
-
-   Notice that the above BSD-style license applies to this one file
-   (memcheck.h) only.  The entire rest of Valgrind is licensed under
-   the terms of the GNU General Public License, version 2.  See the
-   COPYING file in the source distribution for details.
-
-   ---------------------------------------------------------------- 
-*/
-
-
-#ifndef __MEMCHECK_H
-#define __MEMCHECK_H
-
-
-/* This file is for inclusion into client (your!) code.
-
-   You can use these macros to manipulate and query memory permissions
-   inside your own programs.
-
-   See comment near the top of valgrind.h on how to use them.
-*/
-
-#include "valgrind.h"
-
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 
-   This enum comprises an ABI exported by Valgrind to programs
-   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
-   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
-typedef
-   enum { 
-      VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'),
-      VG_USERREQ__MAKE_MEM_UNDEFINED,
-      VG_USERREQ__MAKE_MEM_DEFINED,
-      VG_USERREQ__DISCARD,
-      VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,
-      VG_USERREQ__CHECK_MEM_IS_DEFINED,
-      VG_USERREQ__DO_LEAK_CHECK,
-      VG_USERREQ__COUNT_LEAKS,
-
-      VG_USERREQ__GET_VBITS,
-      VG_USERREQ__SET_VBITS,
-
-      VG_USERREQ__CREATE_BLOCK,
-
-      VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE,
-
-      /* Not next to VG_USERREQ__COUNT_LEAKS because it was added later. */
-      VG_USERREQ__COUNT_LEAK_BLOCKS,
-
-      /* This is just for memcheck's internal use - don't use it */
-      _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR 
-         = VG_USERREQ_TOOL_BASE('M','C') + 256
-   } Vg_MemCheckClientRequest;
-
-
-
-/* Client-code macros to manipulate the state of memory. */
-
-/* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */
-#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len)           \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,      \
-                            VG_USERREQ__MAKE_MEM_NOACCESS,       \
-                            (_qzz_addr), (_qzz_len), 0, 0, 0)
-      
-/* Similarly, mark memory at _qzz_addr as addressable but undefined
-   for _qzz_len bytes. */
-#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len)          \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,      \
-                            VG_USERREQ__MAKE_MEM_UNDEFINED,      \
-                            (_qzz_addr), (_qzz_len), 0, 0, 0)
-
-/* Similarly, mark memory at _qzz_addr as addressable and defined
-   for _qzz_len bytes. */
-#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len)            \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,      \
-                            VG_USERREQ__MAKE_MEM_DEFINED,        \
-                            (_qzz_addr), (_qzz_len), 0, 0, 0)
-
-/* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is
-   not altered: bytes which are addressable are marked as defined,
-   but those which are not addressable are left unchanged. */
-#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len)     \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,              \
-                            VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \
-                            (_qzz_addr), (_qzz_len), 0, 0, 0)
-
-/* Create a block-description handle.  The description is an ascii
-   string which is included in any messages pertaining to addresses
-   within the specified memory range.  Has no other effect on the
-   properties of the memory range. */
-#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc)	   \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,        \
-                            VG_USERREQ__CREATE_BLOCK,              \
-                            (_qzz_addr), (_qzz_len), (_qzz_desc),  \
-                            0, 0)
-
-/* Discard a block-description-handle. Returns 1 for an
-   invalid handle, 0 for a valid handle. */
-#define VALGRIND_DISCARD(_qzz_blkindex)                          \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,      \
-                            VG_USERREQ__DISCARD,                 \
-                            0, (_qzz_blkindex), 0, 0, 0)
-
-
-/* Client-code macros to check the state of memory. */
-
-/* Check that memory at _qzz_addr is addressable for _qzz_len bytes.
-   If suitable addressibility is not established, Valgrind prints an
-   error message and returns the address of the first offending byte.
-   Otherwise it returns zero. */
-#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len)      \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                             \
-                            VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,  \
-                            (_qzz_addr), (_qzz_len), 0, 0, 0)
-
-/* Check that memory at _qzz_addr is addressable and defined for
-   _qzz_len bytes.  If suitable addressibility and definedness are not
-   established, Valgrind prints an error message and returns the
-   address of the first offending byte.  Otherwise it returns zero. */
-#define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len)        \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                           \
-                            VG_USERREQ__CHECK_MEM_IS_DEFINED,    \
-                            (_qzz_addr), (_qzz_len), 0, 0, 0)
-
-/* Use this macro to force the definedness and addressibility of an
-   lvalue to be checked.  If suitable addressibility and definedness
-   are not established, Valgrind prints an error message and returns
-   the address of the first offending byte.  Otherwise it returns
-   zero. */
-#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue)                \
-   VALGRIND_CHECK_MEM_IS_DEFINED(                                \
-      (volatile unsigned char *)&(__lvalue),                     \
-                      (unsigned long)(sizeof (__lvalue)))
-
-
-/* Do a full memory leak check (like --leak-check=full) mid-execution. */
-#define VALGRIND_DO_LEAK_CHECK                                   \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK,   \
-                                    0, 0, 0, 0, 0)
-
-/* Same as VALGRIND_DO_LEAK_CHECK but only showing the entries for
-   which there was an increase in leaked bytes or leaked nr of blocks
-   since the previous leak search. */
-#define VALGRIND_DO_ADDED_LEAK_CHECK                            \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK,  \
-                                    0, 1, 0, 0, 0)
-
-/* Same as VALGRIND_DO_ADDED_LEAK_CHECK but showing entries with
-   increased or decreased leaked bytes/blocks since previous leak
-   search. */
-#define VALGRIND_DO_CHANGED_LEAK_CHECK                          \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK,  \
-                                    0, 2, 0, 0, 0)
-
-/* Do a summary memory leak check (like --leak-check=summary) mid-execution. */
-#define VALGRIND_DO_QUICK_LEAK_CHECK                             \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK,   \
-                                    1, 0, 0, 0, 0)
-
-/* Return number of leaked, dubious, reachable and suppressed bytes found by
-   all previous leak checks.  They must be lvalues.  */
-#define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed)     \
-   /* For safety on 64-bit platforms we assign the results to private
-      unsigned long variables, then assign these to the lvalues the user
-      specified, which works no matter what type 'leaked', 'dubious', etc
-      are.  We also initialise '_qzz_leaked', etc because
-      VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
-      defined. */                                                        \
-   {                                                                     \
-    unsigned long _qzz_leaked    = 0, _qzz_dubious    = 0;               \
-    unsigned long _qzz_reachable = 0, _qzz_suppressed = 0;               \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(                                     \
-                               VG_USERREQ__COUNT_LEAKS,                  \
-                               &_qzz_leaked, &_qzz_dubious,              \
-                               &_qzz_reachable, &_qzz_suppressed, 0);    \
-    leaked     = _qzz_leaked;                                            \
-    dubious    = _qzz_dubious;                                           \
-    reachable  = _qzz_reachable;                                         \
-    suppressed = _qzz_suppressed;                                        \
-   }
-
-/* Return number of leaked, dubious, reachable and suppressed bytes found by
-   all previous leak checks.  They must be lvalues.  */
-#define VALGRIND_COUNT_LEAK_BLOCKS(leaked, dubious, reachable, suppressed) \
-   /* For safety on 64-bit platforms we assign the results to private
-      unsigned long variables, then assign these to the lvalues the user
-      specified, which works no matter what type 'leaked', 'dubious', etc
-      are.  We also initialise '_qzz_leaked', etc because
-      VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
-      defined. */                                                        \
-   {                                                                     \
-    unsigned long _qzz_leaked    = 0, _qzz_dubious    = 0;               \
-    unsigned long _qzz_reachable = 0, _qzz_suppressed = 0;               \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(                                     \
-                               VG_USERREQ__COUNT_LEAK_BLOCKS,            \
-                               &_qzz_leaked, &_qzz_dubious,              \
-                               &_qzz_reachable, &_qzz_suppressed, 0);    \
-    leaked     = _qzz_leaked;                                            \
-    dubious    = _qzz_dubious;                                           \
-    reachable  = _qzz_reachable;                                         \
-    suppressed = _qzz_suppressed;                                        \
-   }
-
-
-/* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it
-   into the provided zzvbits array.  Return values:
-      0   if not running on valgrind
-      1   success
-      2   [previously indicated unaligned arrays;  these are now allowed]
-      3   if any parts of zzsrc/zzvbits are not addressable.
-   The metadata is not copied in cases 0, 2 or 3 so it should be
-   impossible to segfault your system by using this call.
-*/
-#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes)                \
-    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                \
-                                    VG_USERREQ__GET_VBITS,      \
-                                    (const char*)(zza),         \
-                                    (char*)(zzvbits),           \
-                                    (zznbytes), 0, 0)
-
-/* Set the validity data for addresses [zza..zza+zznbytes-1], copying it
-   from the provided zzvbits array.  Return values:
-      0   if not running on valgrind
-      1   success
-      2   [previously indicated unaligned arrays;  these are now allowed]
-      3   if any parts of zza/zzvbits are not addressable.
-   The metadata is not copied in cases 0, 2 or 3 so it should be
-   impossible to segfault your system by using this call.
-*/
-#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes)                \
-    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                \
-                                    VG_USERREQ__SET_VBITS,      \
-                                    (const char*)(zza),         \
-                                    (const char*)(zzvbits),     \
-                                    (zznbytes), 0, 0 )
-
-#endif
diff --git a/src/rt/valgrind/valgrind.h b/src/rt/valgrind/valgrind.h
deleted file mode 100644
index 51f9de8edf0..00000000000
--- a/src/rt/valgrind/valgrind.h
+++ /dev/null
@@ -1,5414 +0,0 @@
-/* -*- c -*-
-   ----------------------------------------------------------------
-
-   Notice that the following BSD-style license applies to this one
-   file (valgrind.h) only.  The rest of Valgrind is licensed under the
-   terms of the GNU General Public License, version 2, unless
-   otherwise indicated.  See the COPYING file in the source
-   distribution for details.
-
-   ----------------------------------------------------------------
-
-   This file is part of Valgrind, a dynamic binary instrumentation
-   framework.
-
-   Copyright (C) 2000-2013 Julian Seward.  All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-   1. Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-   2. The origin of this software must not be misrepresented; you must
-      not claim that you wrote the original software.  If you use this
-      software in a product, an acknowledgment in the product
-      documentation would be appreciated but is not required.
-
-   3. Altered source versions must be plainly marked as such, and must
-      not be misrepresented as being the original software.
-
-   4. The name of the author may not be used to endorse or promote
-      products derived from this software without specific prior written
-      permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-   ----------------------------------------------------------------
-
-   Notice that the above BSD-style license applies to this one file
-   (valgrind.h) only.  The entire rest of Valgrind is licensed under
-   the terms of the GNU General Public License, version 2.  See the
-   COPYING file in the source distribution for details.
-
-   ----------------------------------------------------------------
-*/
-
-
-/* This file is for inclusion into client (your!) code.
-
-   You can use these macros to manipulate and query Valgrind's
-   execution inside your own programs.
-
-   The resulting executables will still run without Valgrind, just a
-   little bit more slowly than they otherwise would, but otherwise
-   unchanged.  When not running on valgrind, each client request
-   consumes very few (eg. 7) instructions, so the resulting performance
-   loss is negligible unless you plan to execute client requests
-   millions of times per second.  Nevertheless, if that is still a
-   problem, you can compile with the NVALGRIND symbol defined (gcc
-   -DNVALGRIND) so that client requests are not even compiled in.  */
-
-#ifndef __VALGRIND_H
-#define __VALGRIND_H
-
-
-/* ------------------------------------------------------------------ */
-/* VERSION NUMBER OF VALGRIND                                         */
-/* ------------------------------------------------------------------ */
-
-/* Specify Valgrind's version number, so that user code can
-   conditionally compile based on our version number.  Note that these
-   were introduced at version 3.6 and so do not exist in version 3.5
-   or earlier.  The recommended way to use them to check for "version
-   X.Y or later" is (eg)
-
-#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__)   \
-    && (__VALGRIND_MAJOR__ > 3                                   \
-        || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
-*/
-#define __VALGRIND_MAJOR__    3
-#define __VALGRIND_MINOR__    8
-
-
-#include <stdarg.h>
-
-/* Nb: this file might be included in a file compiled with -ansi.  So
-   we can't use C++ style "//" comments nor the "asm" keyword (instead
-   use "__asm__"). */
-
-/* Derive some tags indicating what the target platform is.  Note
-   that in this file we're using the compiler's CPP symbols for
-   identifying architectures, which are different to the ones we use
-   within the rest of Valgrind.  Note, __powerpc__ is active for both
-   32 and 64-bit PPC, whereas __powerpc64__ is only active for the
-   latter (on Linux, that is).
-
-   Misc note: how to find out what's predefined in gcc by default:
-   gcc -Wp,-dM somefile.c
-*/
-#undef PLAT_x86_darwin
-#undef PLAT_amd64_darwin
-#undef PLAT_x86_win32
-#undef PLAT_amd64_win64
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_arm_linux
-#undef PLAT_s390x_linux
-#undef PLAT_mips32_linux
-#undef PLAT_mips64_linux
-
-
-#if defined(__APPLE__) && defined(__i386__)
-#  define PLAT_x86_darwin 1
-#elif defined(__APPLE__) && defined(__x86_64__)
-#  define PLAT_amd64_darwin 1
-#elif defined(__MINGW64__) || (defined(_WIN64) && defined(_M_X64))
-#  define PLAT_amd64_win64 1
-#elif defined(__MINGW32__) || defined(__CYGWIN32__) \
-      || (defined(_WIN32) && defined(_M_IX86))
-#  define PLAT_x86_win32 1
-#elif defined(__linux__) && defined(__i386__)
-#  define PLAT_x86_linux 1
-#elif defined(__linux__) && defined(__x86_64__)
-#  define PLAT_amd64_linux 1
-#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
-#  define PLAT_ppc32_linux 1
-#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
-#  define PLAT_ppc64_linux 1
-#elif defined(__linux__) && defined(__arm__)
-#  define PLAT_arm_linux 1
-#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
-#  define PLAT_s390x_linux 1
-#elif defined(__linux__) && defined(__mips__)
-#if (__mips==64)
-#  define PLAT_mips64_linux 1
-#else
-#  define PLAT_mips32_linux 1
-#endif
-#else
-/* If we're not compiling for our target platform, don't generate
-   any inline asms.  */
-#  if !defined(NVALGRIND)
-#    define NVALGRIND 1
-#  endif
-#endif
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
-/* in here of use to end-users -- skip to the next section.           */
-/* ------------------------------------------------------------------ */
-
-/*
- * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
- * request. Accepts both pointers and integers as arguments.
- *
- * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
- * client request that does not return a value.
-
- * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
- * client request and whose value equals the client request result.  Accepts
- * both pointers and integers as arguments.  Note that such calls are not
- * necessarily pure functions -- they may have side effects.
- */
-
-#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
-                                   _zzq_request, _zzq_arg1, _zzq_arg2,  \
-                                   _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
-  do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),   \
-                        (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
-                        (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
-
-#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
-                           _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
-  do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
-                    (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
-                    (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
-
-#if defined(NVALGRIND)
-
-/* Define NVALGRIND to completely remove the Valgrind magic sequence
-   from the compiled code (analogous to NDEBUG's effects on
-   assert()) */
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-        _zzq_default, _zzq_request,                               \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-      (_zzq_default)
-
-#else  /* ! NVALGRIND */
-
-/* The following defines the magic code sequences which the JITter
-   spots and handles magically.  Don't look too closely at them as
-   they will rot your brain.
-
-   The assembly code sequences for all architectures is in this one
-   file.  This is because this file must be stand-alone, and we don't
-   want to have multiple files.
-
-   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
-   value gets put in the return slot, so that everything works when
-   this is executed not under Valgrind.  Args are passed in a memory
-   block, and so there's no intrinsic limit to the number that could
-   be passed, but it's currently five.
-
-   The macro args are:
-      _zzq_rlval    result lvalue
-      _zzq_default  default value (result returned when running on real CPU)
-      _zzq_request  request code
-      _zzq_arg1..5  request params
-
-   The other two macros are used to support function wrapping, and are
-   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
-   guest's NRADDR pseudo-register and whatever other information is
-   needed to safely run the call original from the wrapper: on
-   ppc64-linux, the R2 value at the divert point is also needed.  This
-   information is abstracted into a user-visible type, OrigFn.
-
-   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
-   guest, but guarantees that the branch instruction will not be
-   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
-   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
-   complete inline asm, since it needs to be combined with more magic
-   inline asm stuff to be useful.
-*/
-
-/* ------------------------- x86-{linux,darwin} ---------------- */
-
-#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
-    ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
-
-typedef
-   struct {
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
-                     "roll $29, %%edi ; roll $19, %%edi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-        _zzq_default, _zzq_request,                               \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  __extension__                                                   \
-  ({volatile unsigned int _zzq_args[6];                           \
-    volatile unsigned int _zzq_result;                            \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %EDX = client_request ( %EAX ) */         \
-                     "xchgl %%ebx,%%ebx"                          \
-                     : "=d" (_zzq_result)                         \
-                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_result;                                                  \
-  })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned int __addr;                                 \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %EAX = guest_NRADDR */                    \
-                     "xchgl %%ecx,%%ecx"                          \
-                     : "=a" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_EAX                                 \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* call-noredir *%EAX */                     \
-                     "xchgl %%edx,%%edx\n\t"
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
-                     "xchgl %%edi,%%edi\n\t"                     \
-                     : : : "cc", "memory"                        \
-                    );                                           \
- } while (0)
-
-#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
-
-/* ------------------------- x86-Win32 ------------------------- */
-
-#if defined(PLAT_x86_win32) && !defined(__GNUC__)
-
-typedef
-   struct {
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#if defined(_MSC_VER)
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     __asm rol edi, 3  __asm rol edi, 13          \
-                     __asm rol edi, 29 __asm rol edi, 19
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-        _zzq_default, _zzq_request,                               \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-    valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
-        (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
-        (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
-        (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
-
-static __inline uintptr_t
-valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
-                                uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
-                                uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
-                                uintptr_t _zzq_arg5)
-{
-    volatile uintptr_t _zzq_args[6];
-    volatile unsigned int _zzq_result;
-    _zzq_args[0] = (uintptr_t)(_zzq_request);
-    _zzq_args[1] = (uintptr_t)(_zzq_arg1);
-    _zzq_args[2] = (uintptr_t)(_zzq_arg2);
-    _zzq_args[3] = (uintptr_t)(_zzq_arg3);
-    _zzq_args[4] = (uintptr_t)(_zzq_arg4);
-    _zzq_args[5] = (uintptr_t)(_zzq_arg5);
-    __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
-            __SPECIAL_INSTRUCTION_PREAMBLE
-            /* %EDX = client_request ( %EAX ) */
-            __asm xchg ebx,ebx
-            __asm mov _zzq_result, edx
-    }
-    return _zzq_result;
-}
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned int __addr;                                 \
-    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
-            /* %EAX = guest_NRADDR */                             \
-            __asm xchg ecx,ecx                                    \
-            __asm mov __addr, eax                                 \
-    }                                                             \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_EAX ERROR
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm { __SPECIAL_INSTRUCTION_PREAMBLE                       \
-            __asm xchg edi,edi                                   \
-    }                                                            \
- } while (0)
-
-#else
-#error Unsupported compiler.
-#endif
-
-#endif /* PLAT_x86_win32 */
-
-/* -------------------- amd64-{linux,darwin,win64} ------------- */
-
-#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
-    || defined(PLAT_amd64_win64)
-
-typedef
-   struct {
-      unsigned long long int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
-                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-        _zzq_default, _zzq_request,                               \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-    __extension__                                                 \
-    ({ volatile unsigned long long int _zzq_args[6];              \
-    volatile unsigned long long int _zzq_result;                  \
-    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
-    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %RDX = client_request ( %RAX ) */         \
-                     "xchgq %%rbx,%%rbx"                          \
-                     : "=d" (_zzq_result)                         \
-                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_result;                                                  \
-    })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned long long int __addr;                       \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %RAX = guest_NRADDR */                    \
-                     "xchgq %%rcx,%%rcx"                          \
-                     : "=a" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory"                             \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_RAX                                 \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* call-noredir *%RAX */                     \
-                     "xchgq %%rdx,%%rdx\n\t"
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
-                     "xchgq %%rdi,%%rdi\n\t"                     \
-                     : : : "cc", "memory"                        \
-                    );                                           \
- } while (0)
-
-#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-typedef
-   struct {
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
-                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-        _zzq_default, _zzq_request,                               \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-    __extension__                                                 \
-  ({         unsigned int  _zzq_args[6];                          \
-             unsigned int  _zzq_result;                           \
-             unsigned int* _zzq_ptr;                              \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
-                     "mr 4,%2\n\t" /*ptr*/                        \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"     /*result*/                     \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
-                     : "cc", "memory", "r3", "r4");               \
-    _zzq_result;                                                  \
-    })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    unsigned int __addr;                                          \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory", "r3"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
-                     "or 5,5,5\n\t"                              \
-                    );                                           \
- } while (0)
-
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-typedef
-   struct {
-      unsigned long long int nraddr; /* where's the code? */
-      unsigned long long int r2;  /* what tocptr do we need? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
-                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-        _zzq_default, _zzq_request,                               \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  __extension__                                                   \
-  ({         unsigned long long int  _zzq_args[6];                \
-             unsigned long long int  _zzq_result;                 \
-             unsigned long long int* _zzq_ptr;                    \
-    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
-    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
-    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
-    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
-    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
-    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
-    _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
-                     "mr 4,%2\n\t" /*ptr*/                        \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = client_request ( %R4 ) */           \
-                     "or 1,1,1\n\t"                               \
-                     "mr %0,3"     /*result*/                     \
-                     : "=b" (_zzq_result)                         \
-                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
-                     : "cc", "memory", "r3", "r4");               \
-    _zzq_result;                                                  \
-  })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    unsigned long long int __addr;                                \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR */                     \
-                     "or 2,2,2\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory", "r3"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %R3 = guest_NRADDR_GPR2 */                \
-                     "or 4,4,4\n\t"                               \
-                     "mr %0,3"                                    \
-                     : "=b" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory", "r3"                       \
-                    );                                            \
-    _zzq_orig->r2 = __addr;                                       \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R11 */       \
-                     "or 3,3,3\n\t"
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
-                     "or 5,5,5\n\t"                              \
-                    );                                           \
- } while (0)
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------- arm-linux ------------------------- */
-
-#if defined(PLAT_arm_linux)
-
-typedef
-   struct {
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
-            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
-            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-        _zzq_default, _zzq_request,                               \
-        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-                                                                  \
-  __extension__                                                   \
-  ({volatile unsigned int  _zzq_args[6];                          \
-    volatile unsigned int  _zzq_result;                           \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-    __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
-                     "mov r4, %2\n\t" /*ptr*/                     \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* R3 = client_request ( R4 ) */             \
-                     "orr r10, r10, r10\n\t"                      \
-                     "mov %0, r3"     /*result*/                  \
-                     : "=r" (_zzq_result)                         \
-                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
-                     : "cc","memory", "r3", "r4");                \
-    _zzq_result;                                                  \
-  })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    unsigned int __addr;                                          \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* R3 = guest_NRADDR */                      \
-                     "orr r11, r11, r11\n\t"                      \
-                     "mov %0, r3"                                 \
-                     : "=r" (__addr)                              \
-                     :                                            \
-                     : "cc", "memory", "r3"                       \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* branch-and-link-to-noredir *%R4 */        \
-                     "orr r12, r12, r12\n\t"
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
-                     "orr r9, r9, r9\n\t"                        \
-                     : : : "cc", "memory"                        \
-                    );                                           \
- } while (0)
-
-#endif /* PLAT_arm_linux */
-
-/* ------------------------ s390x-linux ------------------------ */
-
-#if defined(PLAT_s390x_linux)
-
-typedef
-  struct {
-     unsigned long long int nraddr; /* where's the code? */
-  }
-  OrigFn;
-
-/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
- * code. This detection is implemented in platform specific toIR.c
- * (e.g. VEX/priv/guest_s390_decoder.c).
- */
-#define __SPECIAL_INSTRUCTION_PREAMBLE                           \
-                     "lr 15,15\n\t"                              \
-                     "lr 1,1\n\t"                                \
-                     "lr 2,2\n\t"                                \
-                     "lr 3,3\n\t"
-
-#define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
-#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
-#define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
-#define __VEX_INJECT_IR_CODE  "lr 5,5\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
-       _zzq_default, _zzq_request,                               \
-       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
-  __extension__                                                  \
- ({volatile unsigned long long int _zzq_args[6];                 \
-   volatile unsigned long long int _zzq_result;                  \
-   _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
-   _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
-   _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
-   _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
-   _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
-   _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
-   __asm__ volatile(/* r2 = args */                              \
-                    "lgr 2,%1\n\t"                               \
-                    /* r3 = default */                           \
-                    "lgr 3,%2\n\t"                               \
-                    __SPECIAL_INSTRUCTION_PREAMBLE               \
-                    __CLIENT_REQUEST_CODE                        \
-                    /* results = r3 */                           \
-                    "lgr %0, 3\n\t"                              \
-                    : "=d" (_zzq_result)                         \
-                    : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
-                    : "cc", "2", "3", "memory"                   \
-                   );                                            \
-   _zzq_result;                                                  \
- })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
- { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-   volatile unsigned long long int __addr;                       \
-   __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                    __GET_NR_CONTEXT_CODE                        \
-                    "lgr %0, 3\n\t"                              \
-                    : "=a" (__addr)                              \
-                    :                                            \
-                    : "cc", "3", "memory"                        \
-                   );                                            \
-   _zzq_orig->nraddr = __addr;                                   \
- }
-
-#define VALGRIND_CALL_NOREDIR_R1                                 \
-                    __SPECIAL_INSTRUCTION_PREAMBLE               \
-                    __CALL_NO_REDIR_CODE
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
-                     __VEX_INJECT_IR_CODE);                      \
- } while (0)
-
-#endif /* PLAT_s390x_linux */
-
-/* ------------------------- mips32-linux ---------------- */
-
-#if defined(PLAT_mips32_linux)
-
-typedef
-   struct {
-      unsigned int nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-/* .word  0x342
- * .word  0x742
- * .word  0xC2
- * .word  0x4C2*/
-#define __SPECIAL_INSTRUCTION_PREAMBLE          \
-                     "srl $0, $0, 13\n\t"       \
-                     "srl $0, $0, 29\n\t"       \
-                     "srl $0, $0, 3\n\t"        \
-                     "srl $0, $0, 19\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
-       _zzq_default, _zzq_request,                                \
-       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
-  __extension__                                                   \
-  ({ volatile unsigned int _zzq_args[6];                          \
-    volatile unsigned int _zzq_result;                            \
-    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
-    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
-    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
-    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
-    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
-    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
-        __asm__ volatile("move $11, %1\n\t" /*default*/           \
-                     "move $12, %2\n\t" /*ptr*/                   \
-                     __SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* T3 = client_request ( T4 ) */             \
-                     "or $13, $13, $13\n\t"                       \
-                     "move %0, $11\n\t"     /*result*/            \
-                     : "=r" (_zzq_result)                         \
-                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
-                     : "$11", "$12");                             \
-    _zzq_result;                                                  \
-  })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
-    volatile unsigned int __addr;                                 \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
-                     /* %t9 = guest_NRADDR */                     \
-                     "or $14, $14, $14\n\t"                       \
-                     "move %0, $11"     /*result*/                \
-                     : "=r" (__addr)                              \
-                     :                                            \
-                     : "$11"                                      \
-                    );                                            \
-    _zzq_orig->nraddr = __addr;                                   \
-  }
-
-#define VALGRIND_CALL_NOREDIR_T9                                 \
-                     __SPECIAL_INSTRUCTION_PREAMBLE              \
-                     /* call-noredir *%t9 */                     \
-                     "or $15, $15, $15\n\t"
-
-#define VALGRIND_VEX_INJECT_IR()                                 \
- do {                                                            \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
-                     "or $11, $11, $11\n\t"                      \
-                    );                                           \
- } while (0)
-
-
-#endif /* PLAT_mips32_linux */
-
-/* ------------------------- mips64-linux ---------------- */
-
-#if defined(PLAT_mips64_linux)
-
-typedef
-   struct {
-      unsigned long long nraddr; /* where's the code? */
-   }
-   OrigFn;
-
-/* dsll $0,$0, 3
- * dsll $0,$0, 13
- * dsll $0,$0, 29
- * dsll $0,$0, 19*/
-#define __SPECIAL_INSTRUCTION_PREAMBLE                              \
-                     "dsll $0,$0, 3 ; dsll $0,$0,13\n\t"            \
-                     "dsll $0,$0,29 ; dsll $0,$0,19\n\t"
-
-#define VALGRIND_DO_CLIENT_REQUEST_EXPR(                            \
-       _zzq_default, _zzq_request,                                  \
-       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)       \
-  __extension__                                                     \
-  ({ volatile unsigned long long int _zzq_args[6];                  \
-    volatile unsigned long long int _zzq_result;                    \
-    _zzq_args[0] = (unsigned long long int)(_zzq_request);          \
-    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);             \
-    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);             \
-    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);             \
-    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);             \
-    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);             \
-        __asm__ volatile("move $11, %1\n\t" /*default*/             \
-                         "move $12, %2\n\t" /*ptr*/                 \
-                         __SPECIAL_INSTRUCTION_PREAMBLE             \
-                         /* $11 = client_request ( $12 ) */         \
-                         "or $13, $13, $13\n\t"                     \
-                         "move %0, $11\n\t"     /*result*/          \
-                         : "=r" (_zzq_result)                       \
-                         : "r" (_zzq_default), "r" (&_zzq_args[0])  \
-                         : "$11", "$12");                           \
-    _zzq_result;                                                    \
-  })
-
-#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                         \
-  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                     \
-    volatile unsigned long long int __addr;                         \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
-                     /* $11 = guest_NRADDR */                       \
-                     "or $14, $14, $14\n\t"                         \
-                     "move %0, $11"     /*result*/                  \
-                     : "=r" (__addr)                                \
-                     :                                              \
-                     : "$11");                                      \
-    _zzq_orig->nraddr = __addr;                                     \
-  }
-
-#define VALGRIND_CALL_NOREDIR_T9                                    \
-                     __SPECIAL_INSTRUCTION_PREAMBLE                 \
-                     /* call-noredir $25 */                         \
-                     "or $15, $15, $15\n\t"
-
-#define VALGRIND_VEX_INJECT_IR()                                    \
- do {                                                               \
-    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
-                     "or $11, $11, $11\n\t"                         \
-                    );                                              \
- } while (0)
-
-#endif /* PLAT_mips64_linux */
-
-/* Insert assembly code for other platforms here... */
-
-#endif /* NVALGRIND */
-
-
-/* ------------------------------------------------------------------ */
-/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
-/* ugly.  It's the least-worst tradeoff I can think of.               */
-/* ------------------------------------------------------------------ */
-
-/* This section defines magic (a.k.a appalling-hack) macros for doing
-   guaranteed-no-redirection macros, so as to get from function
-   wrappers to the functions they are wrapping.  The whole point is to
-   construct standard call sequences, but to do the call itself with a
-   special no-redirect call pseudo-instruction that the JIT
-   understands and handles specially.  This section is long and
-   repetitious, and I can't see a way to make it shorter.
-
-   The naming scheme is as follows:
-
-      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
-
-   'W' stands for "word" and 'v' for "void".  Hence there are
-   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
-   and for each, the possibility of returning a word-typed result, or
-   no result.
-*/
-
-/* Use these to write the name of your wrapper.  NOTE: duplicates
-   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h.  NOTE also: inserts
-   the default behaviour equivalance class tag "0000" into the name.
-   See pub_tool_redir.h for details -- normally you don't need to
-   think about this, though. */
-
-/* Use an extra level of macroisation so as to ensure the soname/fnname
-   args are fully macro-expanded before pasting them together. */
-#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
-
-#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
-   VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
-
-#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
-   VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
-
-/* Use this macro from within a wrapper function to collect the
-   context (address and possibly other info) of the original function.
-   Once you have that you can then use it in one of the CALL_FN_
-   macros.  The type of the argument _lval is OrigFn. */
-#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
-
-/* Also provide end-user facilities for function replacement, rather
-   than wrapping.  A replacement function differs from a wrapper in
-   that it has no way to get hold of the original function being
-   called, and hence no way to call onwards to it.  In a replacement
-   function, VALGRIND_GET_ORIG_FN always returns zero. */
-
-#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname)                 \
-   VG_CONCAT4(_vgr00000ZU_,soname,_,fnname)
-
-#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname)                 \
-   VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname)
-
-/* Derivatives of the main macros below, for calling functions
-   returning void. */
-
-#define CALL_FN_v_v(fnptr)                                        \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_v(_junk,fnptr); } while (0)
-
-#define CALL_FN_v_W(fnptr, arg1)                                  \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
-
-#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
-
-#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
-
-#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
-
-#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
-
-#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
-
-#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
-   do { volatile unsigned long _junk;                             \
-        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
-
-/* ------------------------- x86-{linux,darwin} ---------------- */
-
-#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
-
-/* These regs are trashed by the hidden call.  No need to mention eax
-   as gcc can already see that, plus causes gcc to bomb. */
-#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
-
-/* Macros to save and align the stack before making a function
-   call and restore it afterwards as gcc may not keep the stack
-   pointer aligned if it doesn't realise calls are being made
-   to other functions. */
-
-#define VALGRIND_ALIGN_STACK               \
-      "movl %%esp,%%edi\n\t"               \
-      "andl $0xfffffff0,%%esp\n\t"
-#define VALGRIND_RESTORE_STACK             \
-      "movl %%edi,%%esp\n\t"
-
-/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $12, %%esp\n\t"                                    \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $8, %%esp\n\t"                                     \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $4, %%esp\n\t"                                     \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $12, %%esp\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $8, %%esp\n\t"                                     \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $4, %%esp\n\t"                                     \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $12, %%esp\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $8, %%esp\n\t"                                     \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11)                          \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "subl $4, %%esp\n\t"                                     \
-         "pushl 44(%%eax)\n\t"                                    \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11,arg12)                    \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "pushl 48(%%eax)\n\t"                                    \
-         "pushl 44(%%eax)\n\t"                                    \
-         "pushl 40(%%eax)\n\t"                                    \
-         "pushl 36(%%eax)\n\t"                                    \
-         "pushl 32(%%eax)\n\t"                                    \
-         "pushl 28(%%eax)\n\t"                                    \
-         "pushl 24(%%eax)\n\t"                                    \
-         "pushl 20(%%eax)\n\t"                                    \
-         "pushl 16(%%eax)\n\t"                                    \
-         "pushl 12(%%eax)\n\t"                                    \
-         "pushl 8(%%eax)\n\t"                                     \
-         "pushl 4(%%eax)\n\t"                                     \
-         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
-         VALGRIND_CALL_NOREDIR_EAX                                \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=a" (_res)                                  \
-         : /*in*/    "a" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_x86_linux || PLAT_x86_darwin */
-
-/* ------------------------ amd64-{linux,darwin} --------------- */
-
-#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
-
-/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
-                            "rdi", "r8", "r9", "r10", "r11"
-
-/* This is all pretty complex.  It's so as to make stack unwinding
-   work reliably.  See bug 243270.  The basic problem is the sub and
-   add of 128 of %rsp in all of the following macros.  If gcc believes
-   the CFA is in %rsp, then unwinding may fail, because what's at the
-   CFA is not what gcc "expected" when it constructs the CFIs for the
-   places where the macros are instantiated.
-
-   But we can't just add a CFI annotation to increase the CFA offset
-   by 128, to match the sub of 128 from %rsp, because we don't know
-   whether gcc has chosen %rsp as the CFA at that point, or whether it
-   has chosen some other register (eg, %rbp).  In the latter case,
-   adding a CFI annotation to change the CFA offset is simply wrong.
-
-   So the solution is to get hold of the CFA using
-   __builtin_dwarf_cfa(), put it in a known register, and add a
-   CFI annotation to say what the register is.  We choose %rbp for
-   this (perhaps perversely), because:
-
-   (1) %rbp is already subject to unwinding.  If a new register was
-       chosen then the unwinder would have to unwind it in all stack
-       traces, which is expensive, and
-
-   (2) %rbp is already subject to precise exception updates in the
-       JIT.  If a new register was chosen, we'd have to have precise
-       exceptions for it too, which reduces performance of the
-       generated code.
-
-   However .. one extra complication.  We can't just whack the result
-   of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
-   list of trashed registers at the end of the inline assembly
-   fragments; gcc won't allow %rbp to appear in that list.  Hence
-   instead we need to stash %rbp in %r15 for the duration of the asm,
-   and say that %r15 is trashed instead.  gcc seems happy to go with
-   that.
-
-   Oh .. and this all needs to be conditionalised so that it is
-   unchanged from before this commit, when compiled with older gccs
-   that don't support __builtin_dwarf_cfa.  Furthermore, since
-   this header file is freestanding, it has to be independent of
-   config.h, and so the following conditionalisation cannot depend on
-   configure time checks.
-
-   Although it's not clear from
-   'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
-   this expression excludes Darwin.
-   .cfi directives in Darwin assembly appear to be completely
-   different and I haven't investigated how they work.
-
-   For even more entertainment value, note we have to use the
-   completely undocumented __builtin_dwarf_cfa(), which appears to
-   really compute the CFA, whereas __builtin_frame_address(0) claims
-   to but actually doesn't.  See
-   https://bugs.kde.org/show_bug.cgi?id=243270#c47
-*/
-#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
-#  define __FRAME_POINTER                                         \
-      ,"r"(__builtin_dwarf_cfa())
-#  define VALGRIND_CFI_PROLOGUE                                   \
-      "movq %%rbp, %%r15\n\t"                                     \
-      "movq %2, %%rbp\n\t"                                        \
-      ".cfi_remember_state\n\t"                                   \
-      ".cfi_def_cfa rbp, 0\n\t"
-#  define VALGRIND_CFI_EPILOGUE                                   \
-      "movq %%r15, %%rbp\n\t"                                     \
-      ".cfi_restore_state\n\t"
-#else
-#  define __FRAME_POINTER
-#  define VALGRIND_CFI_PROLOGUE
-#  define VALGRIND_CFI_EPILOGUE
-#endif
-
-/* Macros to save and align the stack before making a function
-   call and restore it afterwards as gcc may not keep the stack
-   pointer aligned if it doesn't realise calls are being made
-   to other functions. */
-
-#define VALGRIND_ALIGN_STACK               \
-      "movq %%rsp,%%r14\n\t"               \
-      "andq $0xfffffffffffffff0,%%rsp\n\t"
-#define VALGRIND_RESTORE_STACK             \
-      "movq %%r14,%%rsp\n\t"
-
-/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
-   long) == 8. */
-
-/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
-   macros.  In order not to trash the stack redzone, we need to drop
-   %rsp by 128 before the hidden call, and restore afterwards.  The
-   nastyness is that it is only by luck that the stack still appears
-   to be unwindable during the hidden call - since then the behaviour
-   of any routine using this macro does not match what the CFI data
-   says.  Sigh.
-
-   Why is this important?  Imagine that a wrapper has a stack
-   allocated local, and passes to the hidden call, a pointer to it.
-   Because gcc does not know about the hidden call, it may allocate
-   that local in the redzone.  Unfortunately the hidden call may then
-   trash it before it comes to use it.  So we must step clear of the
-   redzone, for the duration of the hidden call, to make it safe.
-
-   Probably the same problem afflicts the other redzone-style ABIs too
-   (ppc64-linux); but for those, the stack is
-   self describing (none of this CFI nonsense) so at least messing
-   with the stack pointer doesn't give a danger of non-unwindable
-   stack. */
-
-#define CALL_FN_W_v(lval, orig)                                        \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[1];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                                  \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[2];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                            \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[3];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                      \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[4];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)                \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[5];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)             \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[6];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)        \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[7];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      _argvec[6] = (unsigned long)(arg6);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "movq 48(%%rax), %%r9\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
-                                 arg7)                                 \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[8];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      _argvec[6] = (unsigned long)(arg6);                              \
-      _argvec[7] = (unsigned long)(arg7);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $136,%%rsp\n\t"                                         \
-         "pushq 56(%%rax)\n\t"                                         \
-         "movq 48(%%rax), %%r9\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
-                                 arg7,arg8)                            \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[9];                               \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      _argvec[6] = (unsigned long)(arg6);                              \
-      _argvec[7] = (unsigned long)(arg7);                              \
-      _argvec[8] = (unsigned long)(arg8);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "pushq 64(%%rax)\n\t"                                         \
-         "pushq 56(%%rax)\n\t"                                         \
-         "movq 48(%%rax), %%r9\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
-                                 arg7,arg8,arg9)                       \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[10];                              \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      _argvec[6] = (unsigned long)(arg6);                              \
-      _argvec[7] = (unsigned long)(arg7);                              \
-      _argvec[8] = (unsigned long)(arg8);                              \
-      _argvec[9] = (unsigned long)(arg9);                              \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $136,%%rsp\n\t"                                         \
-         "pushq 72(%%rax)\n\t"                                         \
-         "pushq 64(%%rax)\n\t"                                         \
-         "pushq 56(%%rax)\n\t"                                         \
-         "movq 48(%%rax), %%r9\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
-                                  arg7,arg8,arg9,arg10)                \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[11];                              \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      _argvec[6] = (unsigned long)(arg6);                              \
-      _argvec[7] = (unsigned long)(arg7);                              \
-      _argvec[8] = (unsigned long)(arg8);                              \
-      _argvec[9] = (unsigned long)(arg9);                              \
-      _argvec[10] = (unsigned long)(arg10);                            \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "pushq 80(%%rax)\n\t"                                         \
-         "pushq 72(%%rax)\n\t"                                         \
-         "pushq 64(%%rax)\n\t"                                         \
-         "pushq 56(%%rax)\n\t"                                         \
-         "movq 48(%%rax), %%r9\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
-                                  arg7,arg8,arg9,arg10,arg11)          \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[12];                              \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      _argvec[6] = (unsigned long)(arg6);                              \
-      _argvec[7] = (unsigned long)(arg7);                              \
-      _argvec[8] = (unsigned long)(arg8);                              \
-      _argvec[9] = (unsigned long)(arg9);                              \
-      _argvec[10] = (unsigned long)(arg10);                            \
-      _argvec[11] = (unsigned long)(arg11);                            \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $136,%%rsp\n\t"                                         \
-         "pushq 88(%%rax)\n\t"                                         \
-         "pushq 80(%%rax)\n\t"                                         \
-         "pushq 72(%%rax)\n\t"                                         \
-         "pushq 64(%%rax)\n\t"                                         \
-         "pushq 56(%%rax)\n\t"                                         \
-         "movq 48(%%rax), %%r9\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
-                                arg7,arg8,arg9,arg10,arg11,arg12)      \
-   do {                                                                \
-      volatile OrigFn        _orig = (orig);                           \
-      volatile unsigned long _argvec[13];                              \
-      volatile unsigned long _res;                                     \
-      _argvec[0] = (unsigned long)_orig.nraddr;                        \
-      _argvec[1] = (unsigned long)(arg1);                              \
-      _argvec[2] = (unsigned long)(arg2);                              \
-      _argvec[3] = (unsigned long)(arg3);                              \
-      _argvec[4] = (unsigned long)(arg4);                              \
-      _argvec[5] = (unsigned long)(arg5);                              \
-      _argvec[6] = (unsigned long)(arg6);                              \
-      _argvec[7] = (unsigned long)(arg7);                              \
-      _argvec[8] = (unsigned long)(arg8);                              \
-      _argvec[9] = (unsigned long)(arg9);                              \
-      _argvec[10] = (unsigned long)(arg10);                            \
-      _argvec[11] = (unsigned long)(arg11);                            \
-      _argvec[12] = (unsigned long)(arg12);                            \
-      __asm__ volatile(                                                \
-         VALGRIND_CFI_PROLOGUE                                         \
-         VALGRIND_ALIGN_STACK                                          \
-         "subq $128,%%rsp\n\t"                                         \
-         "pushq 96(%%rax)\n\t"                                         \
-         "pushq 88(%%rax)\n\t"                                         \
-         "pushq 80(%%rax)\n\t"                                         \
-         "pushq 72(%%rax)\n\t"                                         \
-         "pushq 64(%%rax)\n\t"                                         \
-         "pushq 56(%%rax)\n\t"                                         \
-         "movq 48(%%rax), %%r9\n\t"                                    \
-         "movq 40(%%rax), %%r8\n\t"                                    \
-         "movq 32(%%rax), %%rcx\n\t"                                   \
-         "movq 24(%%rax), %%rdx\n\t"                                   \
-         "movq 16(%%rax), %%rsi\n\t"                                   \
-         "movq 8(%%rax), %%rdi\n\t"                                    \
-         "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
-         VALGRIND_CALL_NOREDIR_RAX                                     \
-         VALGRIND_RESTORE_STACK                                        \
-         VALGRIND_CFI_EPILOGUE                                         \
-         : /*out*/   "=a" (_res)                                       \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
-      );                                                               \
-      lval = (__typeof__(lval)) _res;                                  \
-   } while (0)
-
-#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
-
-/* ------------------------ ppc32-linux ------------------------ */
-
-#if defined(PLAT_ppc32_linux)
-
-/* This is useful for finding out about the on-stack stuff:
-
-   extern int f9  ( int,int,int,int,int,int,int,int,int );
-   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
-   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
-   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
-
-   int g9 ( void ) {
-      return f9(11,22,33,44,55,66,77,88,99);
-   }
-   int g10 ( void ) {
-      return f10(11,22,33,44,55,66,77,88,99,110);
-   }
-   int g11 ( void ) {
-      return f11(11,22,33,44,55,66,77,88,99,110,121);
-   }
-   int g12 ( void ) {
-      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
-   }
-*/
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* Macros to save and align the stack before making a function
-   call and restore it afterwards as gcc may not keep the stack
-   pointer aligned if it doesn't realise calls are being made
-   to other functions. */
-
-#define VALGRIND_ALIGN_STACK               \
-      "mr 28,1\n\t"                        \
-      "rlwinm 1,1,0,0,27\n\t"
-#define VALGRIND_RESTORE_STACK             \
-      "mr 1,28\n\t"
-
-/* These CALL_FN_ macros assume that on ppc32-linux,
-   sizeof(unsigned long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-16\n\t"                                       \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-16\n\t"                                       \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      _argvec[11] = (unsigned long)arg11;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-32\n\t"                                       \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,16(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)arg1;                           \
-      _argvec[2] = (unsigned long)arg2;                           \
-      _argvec[3] = (unsigned long)arg3;                           \
-      _argvec[4] = (unsigned long)arg4;                           \
-      _argvec[5] = (unsigned long)arg5;                           \
-      _argvec[6] = (unsigned long)arg6;                           \
-      _argvec[7] = (unsigned long)arg7;                           \
-      _argvec[8] = (unsigned long)arg8;                           \
-      _argvec[9] = (unsigned long)arg9;                           \
-      _argvec[10] = (unsigned long)arg10;                         \
-      _argvec[11] = (unsigned long)arg11;                         \
-      _argvec[12] = (unsigned long)arg12;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "addi 1,1,-32\n\t"                                       \
-         /* arg12 */                                              \
-         "lwz 3,48(11)\n\t"                                       \
-         "stw 3,20(1)\n\t"                                        \
-         /* arg11 */                                              \
-         "lwz 3,44(11)\n\t"                                       \
-         "stw 3,16(1)\n\t"                                        \
-         /* arg10 */                                              \
-         "lwz 3,40(11)\n\t"                                       \
-         "stw 3,12(1)\n\t"                                        \
-         /* arg9 */                                               \
-         "lwz 3,36(11)\n\t"                                       \
-         "stw 3,8(1)\n\t"                                         \
-         /* args1-8 */                                            \
-         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
-         "lwz 4,8(11)\n\t"                                        \
-         "lwz 5,12(11)\n\t"                                       \
-         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
-         "lwz 7,20(11)\n\t"                                       \
-         "lwz 8,24(11)\n\t"                                       \
-         "lwz 9,28(11)\n\t"                                       \
-         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
-         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         VALGRIND_RESTORE_STACK                                   \
-         "mr %0,3"                                                \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc32_linux */
-
-/* ------------------------ ppc64-linux ------------------------ */
-
-#if defined(PLAT_ppc64_linux)
-
-/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS                                       \
-   "lr", "ctr", "xer",                                            \
-   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
-   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
-   "r11", "r12", "r13"
-
-/* Macros to save and align the stack before making a function
-   call and restore it afterwards as gcc may not keep the stack
-   pointer aligned if it doesn't realise calls are being made
-   to other functions. */
-
-#define VALGRIND_ALIGN_STACK               \
-      "mr 28,1\n\t"                        \
-      "rldicr 1,1,0,59\n\t"
-#define VALGRIND_RESTORE_STACK             \
-      "mr 1,28\n\t"
-
-/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
-   long) == 8. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+0];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1] = (unsigned long)_orig.r2;                       \
-      _argvec[2] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+1];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+2];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+3];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+4];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+5];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+6];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+7];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+8];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+9];                        \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-128\n\t"  /* expand stack frame */            \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+10];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-128\n\t"  /* expand stack frame */            \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10,arg11)     \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+11];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-144\n\t"  /* expand stack frame */            \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                arg7,arg8,arg9,arg10,arg11,arg12) \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3+12];                       \
-      volatile unsigned long _res;                                \
-      /* _argvec[0] holds current r2 across the call */           \
-      _argvec[1]   = (unsigned long)_orig.r2;                     \
-      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
-      _argvec[2+1] = (unsigned long)arg1;                         \
-      _argvec[2+2] = (unsigned long)arg2;                         \
-      _argvec[2+3] = (unsigned long)arg3;                         \
-      _argvec[2+4] = (unsigned long)arg4;                         \
-      _argvec[2+5] = (unsigned long)arg5;                         \
-      _argvec[2+6] = (unsigned long)arg6;                         \
-      _argvec[2+7] = (unsigned long)arg7;                         \
-      _argvec[2+8] = (unsigned long)arg8;                         \
-      _argvec[2+9] = (unsigned long)arg9;                         \
-      _argvec[2+10] = (unsigned long)arg10;                       \
-      _argvec[2+11] = (unsigned long)arg11;                       \
-      _argvec[2+12] = (unsigned long)arg12;                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "mr 11,%1\n\t"                                           \
-         "std 2,-16(11)\n\t"  /* save tocptr */                   \
-         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
-         "addi 1,1,-144\n\t"  /* expand stack frame */            \
-         /* arg12 */                                              \
-         "ld  3,96(11)\n\t"                                       \
-         "std 3,136(1)\n\t"                                       \
-         /* arg11 */                                              \
-         "ld  3,88(11)\n\t"                                       \
-         "std 3,128(1)\n\t"                                       \
-         /* arg10 */                                              \
-         "ld  3,80(11)\n\t"                                       \
-         "std 3,120(1)\n\t"                                       \
-         /* arg9 */                                               \
-         "ld  3,72(11)\n\t"                                       \
-         "std 3,112(1)\n\t"                                       \
-         /* args1-8 */                                            \
-         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
-         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
-         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
-         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
-         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
-         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
-         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
-         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
-         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
-         "mr 11,%1\n\t"                                           \
-         "mr %0,3\n\t"                                            \
-         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
-         VALGRIND_RESTORE_STACK                                   \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[2])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_ppc64_linux */
-
-/* ------------------------- arm-linux ------------------------- */
-
-#if defined(PLAT_arm_linux)
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
-
-/* Macros to save and align the stack before making a function
-   call and restore it afterwards as gcc may not keep the stack
-   pointer aligned if it doesn't realise calls are being made
-   to other functions. */
-
-/* This is a bit tricky.  We store the original stack pointer in r10
-   as it is callee-saves.  gcc doesn't allow the use of r11 for some
-   reason.  Also, we can't directly "bic" the stack pointer in thumb
-   mode since r13 isn't an allowed register number in that context.
-   So use r4 as a temporary, since that is about to get trashed
-   anyway, just after each use of this macro.  Side effect is we need
-   to be very careful about any future changes, since
-   VALGRIND_ALIGN_STACK simply assumes r4 is usable. */
-#define VALGRIND_ALIGN_STACK               \
-      "mov r10, sp\n\t"                    \
-      "mov r4,  sp\n\t"                    \
-      "bic r4,  r4, #7\n\t"                \
-      "mov sp,  r4\n\t"
-#define VALGRIND_RESTORE_STACK             \
-      "mov sp,  r10\n\t"
-
-/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0\n"                                           \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0\n"                                           \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0\n"                                           \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0\n"                                           \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "sub sp, sp, #4 \n\t"                                    \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "push {r0} \n\t"                                         \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "ldr r1, [%1, #24] \n\t"                                 \
-         "push {r0, r1} \n\t"                                     \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "sub sp, sp, #4 \n\t"                                    \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "ldr r1, [%1, #24] \n\t"                                 \
-         "ldr r2, [%1, #28] \n\t"                                 \
-         "push {r0, r1, r2} \n\t"                                 \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "ldr r1, [%1, #24] \n\t"                                 \
-         "ldr r2, [%1, #28] \n\t"                                 \
-         "ldr r3, [%1, #32] \n\t"                                 \
-         "push {r0, r1, r2, r3} \n\t"                             \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "sub sp, sp, #4 \n\t"                                    \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "ldr r1, [%1, #24] \n\t"                                 \
-         "ldr r2, [%1, #28] \n\t"                                 \
-         "ldr r3, [%1, #32] \n\t"                                 \
-         "ldr r4, [%1, #36] \n\t"                                 \
-         "push {r0, r1, r2, r3, r4} \n\t"                         \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #40] \n\t"                                 \
-         "push {r0} \n\t"                                         \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "ldr r1, [%1, #24] \n\t"                                 \
-         "ldr r2, [%1, #28] \n\t"                                 \
-         "ldr r3, [%1, #32] \n\t"                                 \
-         "ldr r4, [%1, #36] \n\t"                                 \
-         "push {r0, r1, r2, r3, r4} \n\t"                         \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11)                          \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "sub sp, sp, #4 \n\t"                                    \
-         "ldr r0, [%1, #40] \n\t"                                 \
-         "ldr r1, [%1, #44] \n\t"                                 \
-         "push {r0, r1} \n\t"                                     \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "ldr r1, [%1, #24] \n\t"                                 \
-         "ldr r2, [%1, #28] \n\t"                                 \
-         "ldr r3, [%1, #32] \n\t"                                 \
-         "ldr r4, [%1, #36] \n\t"                                 \
-         "push {r0, r1, r2, r3, r4} \n\t"                         \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11,arg12)                    \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         VALGRIND_ALIGN_STACK                                     \
-         "ldr r0, [%1, #40] \n\t"                                 \
-         "ldr r1, [%1, #44] \n\t"                                 \
-         "ldr r2, [%1, #48] \n\t"                                 \
-         "push {r0, r1, r2} \n\t"                                 \
-         "ldr r0, [%1, #20] \n\t"                                 \
-         "ldr r1, [%1, #24] \n\t"                                 \
-         "ldr r2, [%1, #28] \n\t"                                 \
-         "ldr r3, [%1, #32] \n\t"                                 \
-         "ldr r4, [%1, #36] \n\t"                                 \
-         "push {r0, r1, r2, r3, r4} \n\t"                         \
-         "ldr r0, [%1, #4] \n\t"                                  \
-         "ldr r1, [%1, #8] \n\t"                                  \
-         "ldr r2, [%1, #12] \n\t"                                 \
-         "ldr r3, [%1, #16] \n\t"                                 \
-         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
-         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
-         VALGRIND_RESTORE_STACK                                   \
-         "mov %0, r0"                                             \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_arm_linux */
-
-/* ------------------------- s390x-linux ------------------------- */
-
-#if defined(PLAT_s390x_linux)
-
-/* Similar workaround as amd64 (see above), but we use r11 as frame
-   pointer and save the old r11 in r7. r11 might be used for
-   argvec, therefore we copy argvec in r1 since r1 is clobbered
-   after the call anyway.  */
-#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
-#  define __FRAME_POINTER                                         \
-      ,"d"(__builtin_dwarf_cfa())
-#  define VALGRIND_CFI_PROLOGUE                                   \
-      ".cfi_remember_state\n\t"                                   \
-      "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
-      "lgr 7,11\n\t"                                              \
-      "lgr 11,%2\n\t"                                             \
-      ".cfi_def_cfa r11, 0\n\t"
-#  define VALGRIND_CFI_EPILOGUE                                   \
-      "lgr 11, 7\n\t"                                             \
-      ".cfi_restore_state\n\t"
-#else
-#  define __FRAME_POINTER
-#  define VALGRIND_CFI_PROLOGUE                                   \
-      "lgr 1,%1\n\t"
-#  define VALGRIND_CFI_EPILOGUE
-#endif
-
-/* Nb: On s390 the stack pointer is properly aligned *at all times*
-   according to the s390 GCC maintainer. (The ABI specification is not
-   precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and
-   VALGRIND_RESTORE_STACK are not defined here. */
-
-/* These regs are trashed by the hidden call. Note that we overwrite
-   r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
-   function a proper return address. All others are ABI defined call
-   clobbers. */
-#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
-                           "f0","f1","f2","f3","f4","f5","f6","f7"
-
-/* Nb: Although r11 is modified in the asm snippets below (inside
-   VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
-   two reasons:
-   (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
-       modified
-   (2) GCC will complain that r11 cannot appear inside a clobber section,
-       when compiled with -O -fno-omit-frame-pointer
- */
-
-#define CALL_FN_W_v(lval, orig)                                  \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long  _argvec[1];                        \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-160\n\t"                                      \
-         "lg 1, 0(1)\n\t"  /* target->r1 */                      \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,160\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-/* The call abi has the arguments in r2-r6 and stack */
-#define CALL_FN_W_W(lval, orig, arg1)                            \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[2];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-160\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,160\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[3];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-160\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,160\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[4];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-160\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,160\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[5];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-160\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,160\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[6];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-160\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,160\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
-                     arg6)                                       \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[7];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      _argvec[6] = (unsigned long)arg6;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-168\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "mvc 160(8,15), 48(1)\n\t"                              \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,168\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
-                     arg6, arg7)                                 \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[8];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      _argvec[6] = (unsigned long)arg6;                          \
-      _argvec[7] = (unsigned long)arg7;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-176\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "mvc 160(8,15), 48(1)\n\t"                              \
-         "mvc 168(8,15), 56(1)\n\t"                              \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,176\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
-                     arg6, arg7 ,arg8)                           \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[9];                         \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      _argvec[6] = (unsigned long)arg6;                          \
-      _argvec[7] = (unsigned long)arg7;                          \
-      _argvec[8] = (unsigned long)arg8;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-184\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "mvc 160(8,15), 48(1)\n\t"                              \
-         "mvc 168(8,15), 56(1)\n\t"                              \
-         "mvc 176(8,15), 64(1)\n\t"                              \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,184\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
-                     arg6, arg7 ,arg8, arg9)                     \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[10];                        \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      _argvec[6] = (unsigned long)arg6;                          \
-      _argvec[7] = (unsigned long)arg7;                          \
-      _argvec[8] = (unsigned long)arg8;                          \
-      _argvec[9] = (unsigned long)arg9;                          \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-192\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "mvc 160(8,15), 48(1)\n\t"                              \
-         "mvc 168(8,15), 56(1)\n\t"                              \
-         "mvc 176(8,15), 64(1)\n\t"                              \
-         "mvc 184(8,15), 72(1)\n\t"                              \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,192\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
-                     arg6, arg7 ,arg8, arg9, arg10)              \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[11];                        \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      _argvec[6] = (unsigned long)arg6;                          \
-      _argvec[7] = (unsigned long)arg7;                          \
-      _argvec[8] = (unsigned long)arg8;                          \
-      _argvec[9] = (unsigned long)arg9;                          \
-      _argvec[10] = (unsigned long)arg10;                        \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-200\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "mvc 160(8,15), 48(1)\n\t"                              \
-         "mvc 168(8,15), 56(1)\n\t"                              \
-         "mvc 176(8,15), 64(1)\n\t"                              \
-         "mvc 184(8,15), 72(1)\n\t"                              \
-         "mvc 192(8,15), 80(1)\n\t"                              \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,200\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
-                     arg6, arg7 ,arg8, arg9, arg10, arg11)       \
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[12];                        \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      _argvec[6] = (unsigned long)arg6;                          \
-      _argvec[7] = (unsigned long)arg7;                          \
-      _argvec[8] = (unsigned long)arg8;                          \
-      _argvec[9] = (unsigned long)arg9;                          \
-      _argvec[10] = (unsigned long)arg10;                        \
-      _argvec[11] = (unsigned long)arg11;                        \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-208\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "mvc 160(8,15), 48(1)\n\t"                              \
-         "mvc 168(8,15), 56(1)\n\t"                              \
-         "mvc 176(8,15), 64(1)\n\t"                              \
-         "mvc 184(8,15), 72(1)\n\t"                              \
-         "mvc 192(8,15), 80(1)\n\t"                              \
-         "mvc 200(8,15), 88(1)\n\t"                              \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,208\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
-                     arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
-   do {                                                          \
-      volatile OrigFn        _orig = (orig);                     \
-      volatile unsigned long _argvec[13];                        \
-      volatile unsigned long _res;                               \
-      _argvec[0] = (unsigned long)_orig.nraddr;                  \
-      _argvec[1] = (unsigned long)arg1;                          \
-      _argvec[2] = (unsigned long)arg2;                          \
-      _argvec[3] = (unsigned long)arg3;                          \
-      _argvec[4] = (unsigned long)arg4;                          \
-      _argvec[5] = (unsigned long)arg5;                          \
-      _argvec[6] = (unsigned long)arg6;                          \
-      _argvec[7] = (unsigned long)arg7;                          \
-      _argvec[8] = (unsigned long)arg8;                          \
-      _argvec[9] = (unsigned long)arg9;                          \
-      _argvec[10] = (unsigned long)arg10;                        \
-      _argvec[11] = (unsigned long)arg11;                        \
-      _argvec[12] = (unsigned long)arg12;                        \
-      __asm__ volatile(                                          \
-         VALGRIND_CFI_PROLOGUE                                   \
-         "aghi 15,-216\n\t"                                      \
-         "lg 2, 8(1)\n\t"                                        \
-         "lg 3,16(1)\n\t"                                        \
-         "lg 4,24(1)\n\t"                                        \
-         "lg 5,32(1)\n\t"                                        \
-         "lg 6,40(1)\n\t"                                        \
-         "mvc 160(8,15), 48(1)\n\t"                              \
-         "mvc 168(8,15), 56(1)\n\t"                              \
-         "mvc 176(8,15), 64(1)\n\t"                              \
-         "mvc 184(8,15), 72(1)\n\t"                              \
-         "mvc 192(8,15), 80(1)\n\t"                              \
-         "mvc 200(8,15), 88(1)\n\t"                              \
-         "mvc 208(8,15), 96(1)\n\t"                              \
-         "lg 1, 0(1)\n\t"                                        \
-         VALGRIND_CALL_NOREDIR_R1                                \
-         "lgr %0, 2\n\t"                                         \
-         "aghi 15,216\n\t"                                       \
-         VALGRIND_CFI_EPILOGUE                                   \
-         : /*out*/   "=d" (_res)                                 \
-         : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
-         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
-      );                                                         \
-      lval = (__typeof__(lval)) _res;                            \
-   } while (0)
-
-
-#endif /* PLAT_s390x_linux */
-
-/* ------------------------- mips32-linux ----------------------- */
-
-#if defined(PLAT_mips32_linux)
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
-"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-"$25", "$31"
-
-/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "subu $29, $29, 16 \n\t"                                 \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 16\n\t"                                  \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-     volatile unsigned long _argvec[2];                           \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "subu $29, $29, 16 \n\t"                                 \
-         "lw $4, 4(%1) \n\t"   /* arg1*/                          \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 16 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory",  __CALLER_SAVED_REGS               \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "subu $29, $29, 16 \n\t"                                 \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 16 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "subu $29, $29, 16 \n\t"                                 \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 16 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "subu $29, $29, 16 \n\t"                                 \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 16 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 24\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 24 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 32\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 24(%1) \n\t"                                     \
-         "nop\n\t"                                                \
-         "sw $4, 20($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 32 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 32\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 24(%1) \n\t"                                     \
-         "sw $4, 20($29) \n\t"                                    \
-         "lw $4, 28(%1) \n\t"                                     \
-         "sw $4, 24($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 32 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 40\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 24(%1) \n\t"                                     \
-         "sw $4, 20($29) \n\t"                                    \
-         "lw $4, 28(%1) \n\t"                                     \
-         "sw $4, 24($29) \n\t"                                    \
-         "lw $4, 32(%1) \n\t"                                     \
-         "sw $4, 28($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 40 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 40\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 24(%1) \n\t"                                     \
-         "sw $4, 20($29) \n\t"                                    \
-         "lw $4, 28(%1) \n\t"                                     \
-         "sw $4, 24($29) \n\t"                                    \
-         "lw $4, 32(%1) \n\t"                                     \
-         "sw $4, 28($29) \n\t"                                    \
-         "lw $4, 36(%1) \n\t"                                     \
-         "sw $4, 32($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 40 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 48\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 24(%1) \n\t"                                     \
-         "sw $4, 20($29) \n\t"                                    \
-         "lw $4, 28(%1) \n\t"                                     \
-         "sw $4, 24($29) \n\t"                                    \
-         "lw $4, 32(%1) \n\t"                                     \
-         "sw $4, 28($29) \n\t"                                    \
-         "lw $4, 36(%1) \n\t"                                     \
-         "sw $4, 32($29) \n\t"                                    \
-         "lw $4, 40(%1) \n\t"                                     \
-         "sw $4, 36($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 48 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11)                          \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 48\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 24(%1) \n\t"                                     \
-         "sw $4, 20($29) \n\t"                                    \
-         "lw $4, 28(%1) \n\t"                                     \
-         "sw $4, 24($29) \n\t"                                    \
-         "lw $4, 32(%1) \n\t"                                     \
-         "sw $4, 28($29) \n\t"                                    \
-         "lw $4, 36(%1) \n\t"                                     \
-         "sw $4, 32($29) \n\t"                                    \
-         "lw $4, 40(%1) \n\t"                                     \
-         "sw $4, 36($29) \n\t"                                    \
-         "lw $4, 44(%1) \n\t"                                     \
-         "sw $4, 40($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 48 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11,arg12)                    \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         "subu $29, $29, 8 \n\t"                                  \
-         "sw $28, 0($29) \n\t"                                    \
-         "sw $31, 4($29) \n\t"                                    \
-         "lw $4, 20(%1) \n\t"                                     \
-         "subu $29, $29, 56\n\t"                                  \
-         "sw $4, 16($29) \n\t"                                    \
-         "lw $4, 24(%1) \n\t"                                     \
-         "sw $4, 20($29) \n\t"                                    \
-         "lw $4, 28(%1) \n\t"                                     \
-         "sw $4, 24($29) \n\t"                                    \
-         "lw $4, 32(%1) \n\t"                                     \
-         "sw $4, 28($29) \n\t"                                    \
-         "lw $4, 36(%1) \n\t"                                     \
-         "sw $4, 32($29) \n\t"                                    \
-         "lw $4, 40(%1) \n\t"                                     \
-         "sw $4, 36($29) \n\t"                                    \
-         "lw $4, 44(%1) \n\t"                                     \
-         "sw $4, 40($29) \n\t"                                    \
-         "lw $4, 48(%1) \n\t"                                     \
-         "sw $4, 44($29) \n\t"                                    \
-         "lw $4, 4(%1) \n\t"                                      \
-         "lw $5, 8(%1) \n\t"                                      \
-         "lw $6, 12(%1) \n\t"                                     \
-         "lw $7, 16(%1) \n\t"                                     \
-         "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "addu $29, $29, 56 \n\t"                                 \
-         "lw $28, 0($29) \n\t"                                    \
-         "lw $31, 4($29) \n\t"                                    \
-         "addu $29, $29, 8 \n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_mips32_linux */
-
-/* ------------------------- mips64-linux ------------------------- */
-
-#if defined(PLAT_mips64_linux)
-
-/* These regs are trashed by the hidden call. */
-#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
-"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
-"$25", "$31"
-
-/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
-   long) == 4. */
-
-#define CALL_FN_W_v(lval, orig)                                   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[1];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      __asm__ volatile(                                           \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "0" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_W(lval, orig, arg1)                             \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[2];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"   /* arg1*/                           \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[3];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[4];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[5];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[6];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[7];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $9, 48(%1)\n\t"                                      \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7)                            \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[8];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $9, 48(%1)\n\t"                                      \
-         "ld $10, 56(%1)\n\t"                                     \
-         "ld $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8)                       \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[9];                          \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      __asm__ volatile(                                           \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $9, 48(%1)\n\t"                                      \
-         "ld $10, 56(%1)\n\t"                                     \
-         "ld $11, 64(%1)\n\t"                                     \
-         "ld $25, 0(%1) \n\t"  /* target->t9 */                   \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
-                                 arg7,arg8,arg9)                  \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[10];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      __asm__ volatile(                                           \
-         "dsubu $29, $29, 8\n\t"                                  \
-         "ld $4, 72(%1)\n\t"                                      \
-         "sd $4, 0($29)\n\t"                                      \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $9, 48(%1)\n\t"                                      \
-         "ld $10, 56(%1)\n\t"                                     \
-         "ld $11, 64(%1)\n\t"                                     \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "daddu $29, $29, 8\n\t"                                  \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
-                                  arg7,arg8,arg9,arg10)           \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[11];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      __asm__ volatile(                                           \
-         "dsubu $29, $29, 16\n\t"                                 \
-         "ld $4, 72(%1)\n\t"                                      \
-         "sd $4, 0($29)\n\t"                                      \
-         "ld $4, 80(%1)\n\t"                                      \
-         "sd $4, 8($29)\n\t"                                      \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $9, 48(%1)\n\t"                                      \
-         "ld $10, 56(%1)\n\t"                                     \
-         "ld $11, 64(%1)\n\t"                                     \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "daddu $29, $29, 16\n\t"                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11)                          \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[12];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      __asm__ volatile(                                           \
-         "dsubu $29, $29, 24\n\t"                                 \
-         "ld $4, 72(%1)\n\t"                                      \
-         "sd $4, 0($29)\n\t"                                      \
-         "ld $4, 80(%1)\n\t"                                      \
-         "sd $4, 8($29)\n\t"                                      \
-         "ld $4, 88(%1)\n\t"                                      \
-         "sd $4, 16($29)\n\t"                                     \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $9, 48(%1)\n\t"                                      \
-         "ld $10, 56(%1)\n\t"                                     \
-         "ld $11, 64(%1)\n\t"                                     \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "daddu $29, $29, 24\n\t"                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
-                                  arg6,arg7,arg8,arg9,arg10,      \
-                                  arg11,arg12)                    \
-   do {                                                           \
-      volatile OrigFn        _orig = (orig);                      \
-      volatile unsigned long _argvec[13];                         \
-      volatile unsigned long _res;                                \
-      _argvec[0] = (unsigned long)_orig.nraddr;                   \
-      _argvec[1] = (unsigned long)(arg1);                         \
-      _argvec[2] = (unsigned long)(arg2);                         \
-      _argvec[3] = (unsigned long)(arg3);                         \
-      _argvec[4] = (unsigned long)(arg4);                         \
-      _argvec[5] = (unsigned long)(arg5);                         \
-      _argvec[6] = (unsigned long)(arg6);                         \
-      _argvec[7] = (unsigned long)(arg7);                         \
-      _argvec[8] = (unsigned long)(arg8);                         \
-      _argvec[9] = (unsigned long)(arg9);                         \
-      _argvec[10] = (unsigned long)(arg10);                       \
-      _argvec[11] = (unsigned long)(arg11);                       \
-      _argvec[12] = (unsigned long)(arg12);                       \
-      __asm__ volatile(                                           \
-         "dsubu $29, $29, 32\n\t"                                 \
-         "ld $4, 72(%1)\n\t"                                      \
-         "sd $4, 0($29)\n\t"                                      \
-         "ld $4, 80(%1)\n\t"                                      \
-         "sd $4, 8($29)\n\t"                                      \
-         "ld $4, 88(%1)\n\t"                                      \
-         "sd $4, 16($29)\n\t"                                     \
-         "ld $4, 96(%1)\n\t"                                      \
-         "sd $4, 24($29)\n\t"                                     \
-         "ld $4, 8(%1)\n\t"                                       \
-         "ld $5, 16(%1)\n\t"                                      \
-         "ld $6, 24(%1)\n\t"                                      \
-         "ld $7, 32(%1)\n\t"                                      \
-         "ld $8, 40(%1)\n\t"                                      \
-         "ld $9, 48(%1)\n\t"                                      \
-         "ld $10, 56(%1)\n\t"                                     \
-         "ld $11, 64(%1)\n\t"                                     \
-         "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
-         VALGRIND_CALL_NOREDIR_T9                                 \
-         "daddu $29, $29, 32\n\t"                                 \
-         "move %0, $2\n"                                          \
-         : /*out*/   "=r" (_res)                                  \
-         : /*in*/    "r" (&_argvec[0])                            \
-         : /*trash*/ "memory", __CALLER_SAVED_REGS                \
-      );                                                          \
-      lval = (__typeof__(lval)) _res;                             \
-   } while (0)
-
-#endif /* PLAT_mips64_linux */
-
-
-/* ------------------------------------------------------------------ */
-/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
-/*                                                                    */
-/* ------------------------------------------------------------------ */
-
-/* Some request codes.  There are many more of these, but most are not
-   exposed to end-user view.  These are the public ones, all of the
-   form 0x1000 + small_number.
-
-   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
-   ones start at 0x2000.
-*/
-
-/* These macros are used by tools -- they must be public, but don't
-   embed them into other programs. */
-#define VG_USERREQ_TOOL_BASE(a,b) \
-   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
-#define VG_IS_TOOL_USERREQ(a, b, v) \
-   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
-
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
-   This enum comprises an ABI exported by Valgrind to programs
-   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
-   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
-typedef
-   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
-          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
-
-          /* These allow any function to be called from the simulated
-             CPU but run on the real CPU.  Nb: the first arg passed to
-             the function is always the ThreadId of the running
-             thread!  So CLIENT_CALL0 actually requires a 1 arg
-             function, etc. */
-          VG_USERREQ__CLIENT_CALL0 = 0x1101,
-          VG_USERREQ__CLIENT_CALL1 = 0x1102,
-          VG_USERREQ__CLIENT_CALL2 = 0x1103,
-          VG_USERREQ__CLIENT_CALL3 = 0x1104,
-
-          /* Can be useful in regression testing suites -- eg. can
-             send Valgrind's output to /dev/null and still count
-             errors. */
-          VG_USERREQ__COUNT_ERRORS = 0x1201,
-
-          /* Allows the client program and/or gdbserver to execute a monitor
-             command. */
-          VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
-
-          /* These are useful and can be interpreted by any tool that
-             tracks malloc() et al, by using vg_replace_malloc.c. */
-          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
-          VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
-          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
-          /* Memory pool support. */
-          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
-          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
-          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
-          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
-          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
-          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
-          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
-          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
-
-          /* Allow printfs to valgrind log. */
-          /* The first two pass the va_list argument by value, which
-             assumes it is the same size as or smaller than a UWord,
-             which generally isn't the case.  Hence are deprecated.
-             The second two pass the vargs by reference and so are
-             immune to this problem. */
-          /* both :: char* fmt, va_list vargs (DEPRECATED) */
-          VG_USERREQ__PRINTF           = 0x1401,
-          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
-          /* both :: char* fmt, va_list* vargs */
-          VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
-          VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
-
-          /* Stack support. */
-          VG_USERREQ__STACK_REGISTER   = 0x1501,
-          VG_USERREQ__STACK_DEREGISTER = 0x1502,
-          VG_USERREQ__STACK_CHANGE     = 0x1503,
-
-          /* Wine support */
-          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
-
-          /* Querying of debug info. */
-          VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,
-
-          /* Disable/enable error reporting level.  Takes a single
-             Word arg which is the delta to this thread's error
-             disablement indicator.  Hence 1 disables or further
-             disables errors, and -1 moves back towards enablement.
-             Other values are not allowed. */
-          VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801,
-
-          /* Initialise IR injection */
-          VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901
-   } Vg_ClientRequest;
-
-#if !defined(__GNUC__)
-#  define __extension__ /* */
-#endif
-
-
-/* Returns the number of Valgrinds this code is running under.  That
-   is, 0 if running natively, 1 if running under Valgrind, 2 if
-   running under Valgrind which is running under another Valgrind,
-   etc. */
-#define RUNNING_ON_VALGRIND                                           \
-    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
-                                    VG_USERREQ__RUNNING_ON_VALGRIND,  \
-                                    0, 0, 0, 0, 0)                    \
-
-
-/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
-   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
-   since it provides a way to make sure valgrind will retranslate the
-   invalidated area.  Returns no value. */
-#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
-                                    _qzz_addr, _qzz_len, 0, 0, 0)
-
-
-/* These requests are for getting Valgrind itself to print something.
-   Possibly with a backtrace.  This is a really ugly hack.  The return value
-   is the number of characters printed, excluding the "**<pid>** " part at the
-   start and the backtrace (if present). */
-
-#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
-/* Modern GCC will optimize the static routine out if unused,
-   and unused attribute will shut down warnings about it.  */
-static int VALGRIND_PRINTF(const char *format, ...)
-   __attribute__((format(__printf__, 1, 2), __unused__));
-#endif
-static int
-#if defined(_MSC_VER)
-__inline
-#endif
-VALGRIND_PRINTF(const char *format, ...)
-{
-#if defined(NVALGRIND)
-   return 0;
-#else /* NVALGRIND */
-#if defined(_MSC_VER) || defined(__MINGW64__)
-   uintptr_t _qzz_res;
-#else
-   unsigned long _qzz_res;
-#endif
-   va_list vargs;
-   va_start(vargs, format);
-#if defined(_MSC_VER) || defined(__MINGW64__)
-   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
-                              VG_USERREQ__PRINTF_VALIST_BY_REF,
-                              (uintptr_t)format,
-                              (uintptr_t)&vargs,
-                              0, 0, 0);
-#else
-   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
-                              VG_USERREQ__PRINTF_VALIST_BY_REF,
-                              (unsigned long)format,
-                              (unsigned long)&vargs,
-                              0, 0, 0);
-#endif
-   va_end(vargs);
-   return (int)_qzz_res;
-#endif /* NVALGRIND */
-}
-
-#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
-static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
-   __attribute__((format(__printf__, 1, 2), __unused__));
-#endif
-static int
-#if defined(_MSC_VER)
-__inline
-#endif
-VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
-{
-#if defined(NVALGRIND)
-   return 0;
-#else /* NVALGRIND */
-#if defined(_MSC_VER) || defined(__MINGW64__)
-   uintptr_t _qzz_res;
-#else
-   unsigned long _qzz_res;
-#endif
-   va_list vargs;
-   va_start(vargs, format);
-#if defined(_MSC_VER) || defined(__MINGW64__)
-   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
-                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
-                              (uintptr_t)format,
-                              (uintptr_t)&vargs,
-                              0, 0, 0);
-#else
-   _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
-                              VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
-                              (unsigned long)format,
-                              (unsigned long)&vargs,
-                              0, 0, 0);
-#endif
-   va_end(vargs);
-   return (int)_qzz_res;
-#endif /* NVALGRIND */
-}
-
-
-/* These requests allow control to move from the simulated CPU to the
-   real CPU, calling an arbitrary function.
-
-   Note that the current ThreadId is inserted as the first argument.
-   So this call:
-
-     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
-
-   requires f to have this signature:
-
-     Word f(Word tid, Word arg1, Word arg2)
-
-   where "Word" is a word-sized type.
-
-   Note that these client requests are not entirely reliable.  For example,
-   if you call a function with them that subsequently calls printf(),
-   there's a high chance Valgrind will crash.  Generally, your prospects of
-   these working are made higher if the called function does not refer to
-   any global variables, and does not refer to any libc or other functions
-   (printf et al).  Any kind of entanglement with libc or dynamic linking is
-   likely to have a bad outcome, for tricky reasons which we've grappled
-   with a lot in the past.
-*/
-#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
-                                    VG_USERREQ__CLIENT_CALL0,     \
-                                    _qyy_fn,                      \
-                                    0, 0, 0, 0)
-
-#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
-                                    VG_USERREQ__CLIENT_CALL1,          \
-                                    _qyy_fn,                           \
-                                    _qyy_arg1, 0, 0, 0)
-
-#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
-                                    VG_USERREQ__CLIENT_CALL2,          \
-                                    _qyy_fn,                           \
-                                    _qyy_arg1, _qyy_arg2, 0, 0)
-
-#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
-    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
-                                    VG_USERREQ__CLIENT_CALL3,           \
-                                    _qyy_fn,                            \
-                                    _qyy_arg1, _qyy_arg2,               \
-                                    _qyy_arg3, 0)
-
-
-/* Counts the number of errors that have been recorded by a tool.  Nb:
-   the tool must record the errors with VG_(maybe_record_error)() or
-   VG_(unique_error)() for them to be counted. */
-#define VALGRIND_COUNT_ERRORS                                     \
-    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
-                               0 /* default return */,            \
-                               VG_USERREQ__COUNT_ERRORS,          \
-                               0, 0, 0, 0, 0)
-
-/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
-   when heap blocks are allocated in order to give accurate results.  This
-   happens automatically for the standard allocator functions such as
-   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
-   delete[], etc.
-
-   But if your program uses a custom allocator, this doesn't automatically
-   happen, and Valgrind will not do as well.  For example, if you allocate
-   superblocks with mmap() and then allocates chunks of the superblocks, all
-   Valgrind's observations will be at the mmap() level and it won't know that
-   the chunks should be considered separate entities.  In Memcheck's case,
-   that means you probably won't get heap block overrun detection (because
-   there won't be redzones marked as unaddressable) and you definitely won't
-   get any leak detection.
-
-   The following client requests allow a custom allocator to be annotated so
-   that it can be handled accurately by Valgrind.
-
-   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
-   by a malloc()-like function.  For Memcheck (an illustrative case), this
-   does two things:
-
-   - It records that the block has been allocated.  This means any addresses
-     within the block mentioned in error messages will be
-     identified as belonging to the block.  It also means that if the block
-     isn't freed it will be detected by the leak checker.
-
-   - It marks the block as being addressable and undefined (if 'is_zeroed' is
-     not set), or addressable and defined (if 'is_zeroed' is set).  This
-     controls how accesses to the block by the program are handled.
-
-   'addr' is the start of the usable block (ie. after any
-   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
-   can apply redzones -- these are blocks of padding at the start and end of
-   each block.  Adding redzones is recommended as it makes it much more likely
-   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
-   zeroed (or filled with another predictable value), as is the case for
-   calloc().
-
-   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
-   heap block -- that will be used by the client program -- is allocated.
-   It's best to put it at the outermost level of the allocator if possible;
-   for example, if you have a function my_alloc() which calls
-   internal_alloc(), and the client request is put inside internal_alloc(),
-   stack traces relating to the heap block will contain entries for both
-   my_alloc() and internal_alloc(), which is probably not what you want.
-
-   For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
-   custom blocks from within a heap block, B, that has been allocated with
-   malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
-   -- the custom blocks will take precedence.
-
-   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
-   Memcheck, it does two things:
-
-   - It records that the block has been deallocated.  This assumes that the
-     block was annotated as having been allocated via
-     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
-
-   - It marks the block as being unaddressable.
-
-   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
-   heap block is deallocated.
-
-   VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
-   Memcheck, it does four things:
-
-   - It records that the size of a block has been changed.  This assumes that
-     the block was annotated as having been allocated via
-     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
-
-   - If the block shrunk, it marks the freed memory as being unaddressable.
-
-   - If the block grew, it marks the new area as undefined and defines a red
-     zone past the end of the new block.
-
-   - The V-bits of the overlap between the old and the new block are preserved.
-
-   VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
-   and before deallocation of the old block.
-
-   In many cases, these three client requests will not be enough to get your
-   allocator working well with Memcheck.  More specifically, if your allocator
-   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
-   will be necessary to mark the memory as addressable just before the zeroing
-   occurs, otherwise you'll get a lot of invalid write errors.  For example,
-   you'll need to do this if your allocator recycles freed blocks, but it
-   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
-   Alternatively, if your allocator reuses freed blocks for allocator-internal
-   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
-
-   Really, what's happening is a blurring of the lines between the client
-   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
-   memory should be considered unaddressable to the client program, but the
-   allocator knows more than the rest of the client program and so may be able
-   to safely access it.  Extra client requests are necessary for Valgrind to
-   understand the distinction between the allocator and the rest of the
-   program.
-
-   Ignored if addr == 0.
-*/
-#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)          \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK,       \
-                                    addr, sizeB, rzB, is_zeroed, 0)
-
-/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
-   Ignored if addr == 0.
-*/
-#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)     \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK,    \
-                                    addr, oldSizeB, newSizeB, rzB, 0)
-
-/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
-   Ignored if addr == 0.
-*/
-#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                              \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK,         \
-                                    addr, rzB, 0, 0, 0)
-
-/* Create a memory pool. */
-#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,   \
-                                    pool, rzB, is_zeroed, 0, 0)
-
-/* Destroy a memory pool. */
-#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL,  \
-                                    pool, 0, 0, 0, 0)
-
-/* Associate a piece of memory with a memory pool. */
-#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC,    \
-                                    pool, addr, size, 0, 0)
-
-/* Disassociate a piece of memory from a memory pool. */
-#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE,     \
-                                    pool, addr, 0, 0, 0)
-
-/* Disassociate any pieces outside a particular range. */
-#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM,     \
-                                    pool, addr, size, 0, 0)
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL,     \
-                                    poolA, poolB, 0, 0, 0)
-
-/* Resize and/or move a piece associated with a memory pool. */
-#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE,   \
-                                    pool, addrA, addrB, size, 0)
-
-/* Return 1 if a mempool exists, else 0. */
-#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
-    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
-                               VG_USERREQ__MEMPOOL_EXISTS,        \
-                               pool, 0, 0, 0, 0)
-
-/* Mark a piece of memory as being a stack. Returns a stack id. */
-#define VALGRIND_STACK_REGISTER(start, end)                       \
-    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
-                               VG_USERREQ__STACK_REGISTER,        \
-                               start, end, 0, 0, 0)
-
-/* Unmark the piece of memory associated with a stack id as being a
-   stack. */
-#define VALGRIND_STACK_DEREGISTER(id)                             \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
-                                    id, 0, 0, 0, 0)
-
-/* Change the start and end address of the stack id. */
-#define VALGRIND_STACK_CHANGE(id, start, end)                     \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE,     \
-                                    id, start, end, 0, 0)
-
-/* Load PDB debug info for Wine PE image_map. */
-#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)     \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
-                                    fd, ptr, total_size, delta, 0)
-
-/* Map a code address to a source file name and line number.  buf64
-   must point to a 64-byte buffer in the caller's address space.  The
-   result will be dumped in there and is guaranteed to be zero
-   terminated.  If no info is found, the first byte is set to zero. */
-#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
-    (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
-                               VG_USERREQ__MAP_IP_TO_SRCLOC,      \
-                               addr, buf64, 0, 0, 0)
-
-/* Disable error reporting for this thread.  Behaves in a stack like
-   way, so you can safely call this multiple times provided that
-   VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
-   to re-enable reporting.  The first call of this macro disables
-   reporting.  Subsequent calls have no effect except to increase the
-   number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
-   reporting.  Child threads do not inherit this setting from their
-   parents -- they are always created with reporting enabled. */
-#define VALGRIND_DISABLE_ERROR_REPORTING                                \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
-                                    1, 0, 0, 0, 0)
-
-/* Re-enable error reporting, as per comments on
-   VALGRIND_DISABLE_ERROR_REPORTING. */
-#define VALGRIND_ENABLE_ERROR_REPORTING                                 \
-    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
-                                    -1, 0, 0, 0, 0)
-
-/* Execute a monitor command from the client program.
-   If a connection is opened with GDB, the output will be sent
-   according to the output mode set for vgdb.
-   If no connection is opened, output will go to the log output.
-   Returns 1 if command not recognised, 0 otherwise. */
-#define VALGRIND_MONITOR_COMMAND(command)                               \
-   VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \
-                                   command, 0, 0, 0, 0)
-
-
-#undef PLAT_x86_darwin
-#undef PLAT_amd64_darwin
-#undef PLAT_x86_win32
-#undef PLAT_amd64_win64
-#undef PLAT_x86_linux
-#undef PLAT_amd64_linux
-#undef PLAT_ppc32_linux
-#undef PLAT_ppc64_linux
-#undef PLAT_arm_linux
-#undef PLAT_s390x_linux
-#undef PLAT_mips32_linux
-#undef PLAT_mips64_linux
-
-#endif   /* __VALGRIND_H */
diff --git a/src/snapshots.txt b/src/snapshots.txt
index d317b5be4c1..31803fb18f6 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,5 +1,6 @@
 S 2015-07-26 a5c12f4
   bitrig-x86_64 8734eb41ffbe6ddc1120aa2910db4162ec9cf270
+  freebsd-i386 2fee22adec101e2f952a5548fd1437ce1bd8d26f
   freebsd-x86_64 bc50b0f8d7f6d62f4f5ffa136f5387f5bf6524fd
   linux-i386 3459275cdf3896f678e225843fa56f0d9fdbabe8
   linux-x86_64 e451e3bd6e5fcef71e41ae6f3da9fb1cf0e13a0c
diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs
index 4b60a370187..fa5f7f48ab4 100644
--- a/src/test/auxiliary/lang-item-public.rs
+++ b/src/test/auxiliary/lang-item-public.rs
@@ -21,6 +21,9 @@ extern fn stack_exhausted() {}
 #[lang = "eh_personality"]
 extern fn eh_personality() {}
 
+#[lang = "eh_unwind_resume"]
+extern fn eh_unwind_resume() {}
+
 #[lang = "panic_fmt"]
 extern fn rust_begin_unwind(msg: core::fmt::Arguments, file: &'static str,
                             line: u32) -> ! {
diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs
index ca5a7b75e06..11de43a6b92 100644
--- a/src/test/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/auxiliary/lint_group_plugin_test.rs
@@ -20,7 +20,6 @@ extern crate syntax;
 extern crate rustc;
 
 use syntax::ast;
-use syntax::parse::token;
 use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
 use rustc::plugin::Registry;
 
@@ -36,11 +35,10 @@ impl LintPass for Pass {
     }
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        let name = token::get_ident(it.ident);
-        if &name[..] == "lintme" {
-            cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
-        } else if &name[..] == "pleaselintme" {
-            cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'");
+        match &*it.ident.name.as_str() {
+            "lintme" => cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"),
+            "pleaselintme" => cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"),
+            _ => {}
         }
     }
 }
diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs
index 20799ce5b46..967b168d000 100644
--- a/src/test/auxiliary/lint_plugin_test.rs
+++ b/src/test/auxiliary/lint_plugin_test.rs
@@ -20,7 +20,6 @@ extern crate syntax;
 extern crate rustc;
 
 use syntax::ast;
-use syntax::parse::token;
 use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
 use rustc::plugin::Registry;
 
@@ -34,8 +33,7 @@ impl LintPass for Pass {
     }
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        let name = token::get_ident(it.ident);
-        if &name[..] == "lintme" {
+        if it.ident.name == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
         }
     }
diff --git a/src/test/auxiliary/roman_numerals.rs b/src/test/auxiliary/roman_numerals.rs
index 855708535f1..e6f375354aa 100644
--- a/src/test/auxiliary/roman_numerals.rs
+++ b/src/test/auxiliary/roman_numerals.rs
@@ -18,8 +18,8 @@ extern crate syntax;
 extern crate rustc;
 
 use syntax::codemap::Span;
-use syntax::parse::token;
 use syntax::ast::{TokenTree, TtToken};
+use syntax::parse::token;
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax::ext::build::AstBuilder;  // trait for expr_usize
 use rustc::plugin::Registry;
@@ -40,7 +40,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         ("I",    1)];
 
     let text = match args {
-        [TtToken(_, token::Ident(s, _))] => token::get_ident(s).to_string(),
+        [TtToken(_, token::Ident(s, _))] => s.to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
             return DummyResult::any(sp);
diff --git a/src/test/auxiliary/xcrate_associated_type_defaults.rs b/src/test/auxiliary/xcrate_associated_type_defaults.rs
index a6b70bf974f..43852a4e793 100644
--- a/src/test/auxiliary/xcrate_associated_type_defaults.rs
+++ b/src/test/auxiliary/xcrate_associated_type_defaults.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_type_defaults)]
+
 pub trait Foo {
     type Input = usize;
     fn bar(&self, _: Self::Input) {}
diff --git a/src/test/codegen/link_section.rs b/src/test/codegen/link_section.rs
new file mode 100644
index 00000000000..99b43552b0d
--- /dev/null
+++ b/src/test/codegen/link_section.rs
@@ -0,0 +1,36 @@
+// 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.
+
+// compile-flags: -C no-prepopulate-passes
+
+// CHECK: @VAR1 = constant i32 1, section ".test_one"
+#[no_mangle]
+#[link_section = ".test_one"]
+pub static VAR1: u32 = 1;
+
+pub enum E {
+    A(u32),
+    B(f32)
+}
+
+// CHECK: @VAR2 = constant {{.*}} { i32 0, i32 666, {{.*}} }, section ".test_two"
+#[no_mangle]
+#[link_section = ".test_two"]
+pub static VAR2: E = E::A(666);
+
+// CHECK: @VAR3 = constant {{.*}} { i32 1, float 1.000000e+00, {{.*}} }, section ".test_three"
+#[no_mangle]
+#[link_section = ".test_three"]
+pub static VAR3: E = E::B(1.);
+
+// CHECK: define void @fn1() {{.*}} section ".test_four" {
+#[no_mangle]
+#[link_section = ".test_four"]
+pub fn fn1() {}
diff --git a/src/test/compile-fail/associated-types-overridden-default.rs b/src/test/compile-fail/associated-types-overridden-default.rs
index eb519e79006..19f13f5fc2f 100644
--- a/src/test/compile-fail/associated-types-overridden-default.rs
+++ b/src/test/compile-fail/associated-types-overridden-default.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![feature(associated_consts)]
+#![feature(associated_type_defaults)]
 
 pub trait Tr {
     type Assoc = u8;
diff --git a/src/test/compile-fail/bad-expr-lhs.rs b/src/test/compile-fail/bad-expr-lhs.rs
index 6907bf4b5b8..c7d2f2c472f 100644
--- a/src/test/compile-fail/bad-expr-lhs.rs
+++ b/src/test/compile-fail/bad-expr-lhs.rs
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 fn main() {
-    1 = 2; //~ ERROR illegal left-hand side expression
-    1 += 2; //~ ERROR illegal left-hand side expression
-    (1, 2) = (3, 4); //~ ERROR illegal left-hand side expression
+    1 = 2; //~ ERROR invalid left-hand side expression
+    1 += 2; //~ ERROR invalid left-hand side expression
+    (1, 2) = (3, 4); //~ ERROR invalid left-hand side expression
 
     let (a, b) = (1, 2);
-    (a, b) = (3, 4); //~ ERROR illegal left-hand side expression
+    (a, b) = (3, 4); //~ ERROR invalid left-hand side expression
 
-    None = Some(3); //~ ERROR illegal left-hand side expression
+    None = Some(3); //~ ERROR invalid left-hand side expression
 }
diff --git a/src/test/compile-fail/bad-lint-cap.rs b/src/test/compile-fail/bad-lint-cap.rs
new file mode 100644
index 00000000000..cb9c347af60
--- /dev/null
+++ b/src/test/compile-fail/bad-lint-cap.rs
@@ -0,0 +1,14 @@
+// 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.
+
+// compile-flags: --cap-lints test
+// error-pattern: unknown lint level: `test`
+
+fn main() {}
diff --git a/src/test/compile-fail/bad-lint-cap2.rs b/src/test/compile-fail/bad-lint-cap2.rs
new file mode 100644
index 00000000000..5a97d7b1a79
--- /dev/null
+++ b/src/test/compile-fail/bad-lint-cap2.rs
@@ -0,0 +1,17 @@
+// 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.
+
+// compile-flags: --cap-lints deny
+
+#![deny(warnings)]
+
+use std::option; //~ ERROR
+
+fn main() {}
diff --git a/src/test/compile-fail/bad-lint-cap3.rs b/src/test/compile-fail/bad-lint-cap3.rs
new file mode 100644
index 00000000000..e03ba6ecb64
--- /dev/null
+++ b/src/test/compile-fail/bad-lint-cap3.rs
@@ -0,0 +1,20 @@
+// 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.
+
+// compile-flags: --cap-lints warn
+
+#![deny(warnings)]
+#![feature(rustc_attrs)]
+
+use std::option; //~ WARN
+
+#[rustc_error]
+fn main() {} //~ ERROR: compilation successful
+
diff --git a/src/test/compile-fail/cast-as-bool.rs b/src/test/compile-fail/cast-as-bool.rs
index 6d68f56b2b1..92cbbaa1cb4 100644
--- a/src/test/compile-fail/cast-as-bool.rs
+++ b/src/test/compile-fail/cast-as-bool.rs
@@ -8,5 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: cannot cast as `bool`, compare with zero instead
-fn main() { let u = (5 as bool); }
+fn main() {
+    let u = (5 as bool);
+    //~^ ERROR cannot cast as `bool`
+    //~^^ HELP compare with zero instead
+}
diff --git a/src/test/compile-fail/cast-rfc0401.rs b/src/test/compile-fail/cast-rfc0401.rs
index 29ce8c15143..7fca4aece69 100644
--- a/src/test/compile-fail/cast-rfc0401.rs
+++ b/src/test/compile-fail/cast-rfc0401.rs
@@ -10,12 +10,16 @@
 
 fn illegal_cast<U:?Sized,V:?Sized>(u: *const U) -> *const V
 {
-    u as *const V //~ ERROR vtable kinds
+    u as *const V
+    //~^ ERROR casting
+    //~^^ NOTE vtable kinds
 }
 
 fn illegal_cast_2<U:?Sized>(u: *const U) -> *const str
 {
-    u as *const str //~ ERROR vtable kinds
+    u as *const str
+    //~^ ERROR casting
+    //~^^ NOTE vtable kinds
 }
 
 trait Foo { fn foo(&self) {} }
@@ -41,32 +45,58 @@ fn main()
     let _ = v as (u32,); //~ ERROR non-scalar
     let _ = Some(&v) as *const u8; //~ ERROR non-scalar
 
-    let _ = v as f32; //~ ERROR through a usize first
-    let _ = main as f64; //~ ERROR through a usize first
-    let _ = &v as usize; //~ ERROR through a raw pointer first
-    let _ = f as *const u8; //~ ERROR through a usize first
-    let _ = 3 as bool; //~ ERROR compare with zero
-    let _ = E::A as bool; //~ ERROR compare with zero
+    let _ = v as f32;
+    //~^ ERROR casting
+    //~^^ HELP through a usize first
+    let _ = main as f64;
+    //~^ ERROR casting
+    //~^^ HELP through a usize first
+    let _ = &v as usize;
+    //~^ ERROR casting
+    //~^^ HELP through a raw pointer first
+    let _ = f as *const u8;
+    //~^ ERROR casting
+    //~^^ HELP through a usize first
+    let _ = 3 as bool;
+    //~^ ERROR cannot cast as `bool`
+    //~^^ HELP compare with zero
+    let _ = E::A as bool;
+    //~^ ERROR cannot cast as `bool`
+    //~^^ HELP compare with zero
     let _ = 0x61u32 as char; //~ ERROR only `u8` can be cast
 
-    let _ = false as f32; //~ ERROR through an integer first
-    let _ = E::A as f32; //~ ERROR through an integer first
-    let _ = 'a' as f32; //~ ERROR through an integer first
+    let _ = false as f32;
+    //~^ ERROR casting
+    //~^^ HELP through an integer first
+    let _ = E::A as f32;
+    //~^ ERROR casting
+    //~^^ HELP through an integer first
+    let _ = 'a' as f32;
+    //~^ ERROR casting
+    //~^^ HELP through an integer first
 
-    let _ = false as *const u8; //~ ERROR through a usize first
-    let _ = E::A as *const u8; //~ ERROR through a usize first
-    let _ = 'a' as *const u8; //~ ERROR through a usize first
+    let _ = false as *const u8;
+    //~^ ERROR casting
+    //~^^ HELP through a usize first
+    let _ = E::A as *const u8;
+    //~^ ERROR casting
+    //~^^ HELP through a usize first
+    let _ = 'a' as *const u8;
+    //~^ ERROR casting
+    //~^^ HELP through a usize first
 
-    let _ = 42usize as *const [u8]; //~ ERROR illegal cast
-    let _ = v as *const [u8]; //~ ERROR illegal cast
+    let _ = 42usize as *const [u8]; //~ ERROR casting
+    let _ = v as *const [u8]; //~ ERROR casting
     let _ = fat_v as *const Foo;
     //~^ ERROR `core::marker::Sized` is not implemented for the type `[u8]`
-    let _ = foo as *const str; //~ ERROR illegal cast
-    let _ = foo as *mut str; //~ ERROR illegal cast
-    let _ = main as *mut str; //~ ERROR illegal cast
-    let _ = &f as *mut f32; //~ ERROR illegal cast
-    let _ = &f as *const f64; //~ ERROR illegal cast
-    let _ = fat_v as usize; //~ ERROR through a raw pointer first
+    let _ = foo as *const str; //~ ERROR casting
+    let _ = foo as *mut str; //~ ERROR casting
+    let _ = main as *mut str; //~ ERROR casting
+    let _ = &f as *mut f32; //~ ERROR casting
+    let _ = &f as *const f64; //~ ERROR casting
+    let _ = fat_v as usize;
+    //~^ ERROR casting
+    //~^^ HELP through a raw pointer first
 
     let a : *const str = "hello";
     let _ = a as *const Foo;
@@ -76,6 +106,10 @@ fn main()
     let _ = main.f as *const u32; //~ ERROR attempted access of field
 
     let cf: *const Foo = &0;
-    let _ = cf as *const [u8]; //~ ERROR vtable kinds
-    let _ = cf as *const Bar; //~ ERROR vtable kinds
+    let _ = cf as *const [u8];
+    //~^ ERROR casting
+    //~^^ NOTE vtable kinds
+    let _ = cf as *const Bar;
+    //~^ ERROR casting
+    //~^^ NOTE vtable kinds
 }
diff --git a/src/test/compile-fail/const-cast-different-types.rs b/src/test/compile-fail/const-cast-different-types.rs
index e6851f02cb6..397804566b4 100644
--- a/src/test/compile-fail/const-cast-different-types.rs
+++ b/src/test/compile-fail/const-cast-different-types.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 static a: &'static str = "foo";
-static b: *const u8 = a as *const u8; //~ ERROR illegal cast
-static c: *const u8 = &a as *const u8; //~ ERROR illegal cast
+static b: *const u8 = a as *const u8; //~ ERROR casting
+static c: *const u8 = &a as *const u8; //~ ERROR casting
 
 fn main() {
 }
diff --git a/src/test/compile-fail/dropck_misc_variants.rs b/src/test/compile-fail/dropck_misc_variants.rs
new file mode 100644
index 00000000000..ee957f20d00
--- /dev/null
+++ b/src/test/compile-fail/dropck_misc_variants.rs
@@ -0,0 +1,47 @@
+// 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 dropck does the right thing with misc. Ty variants
+
+use std::fmt;
+struct NoisyDrop<T: fmt::Debug>(T);
+impl<T: fmt::Debug> Drop for NoisyDrop<T> {
+    fn drop(&mut self) {
+        let _ = vec!["0wned"];
+        println!("dropping {:?}", self.0)
+    }
+}
+
+trait Associator {
+    type As;
+}
+impl<T: fmt::Debug> Associator for T {
+    type As = NoisyDrop<T>;
+}
+struct Wrap<A: Associator>(<A as Associator>::As);
+
+fn projection() {
+    let (_w, bomb);
+    bomb = vec![""];
+    _w = Wrap::<&[&str]>(NoisyDrop(&bomb));
+    //~^ ERROR `bomb` does not live long enough
+}
+
+fn closure() {
+    let (_w,v);
+    v = vec![""];
+    _w = {
+        let u = NoisyDrop(&v);
+        //~^ ERROR `v` does not live long enough
+        move || u.0.len()
+    };
+}
+
+fn main() { closure(); projection() }
diff --git a/src/test/compile-fail/enum-to-float-cast-2.rs b/src/test/compile-fail/enum-to-float-cast-2.rs
index 7ee67131755..e6f473c8aac 100644
--- a/src/test/compile-fail/enum-to-float-cast-2.rs
+++ b/src/test/compile-fail/enum-to-float-cast-2.rs
@@ -21,8 +21,8 @@ enum F {
 }
 
 pub fn main() {
-    let a = E::L0 as f32;  //~ ERROR illegal cast
-    let c = F::H1 as f32;  //~ ERROR illegal cast
+    let a = E::L0 as f32;  //~ ERROR casting
+    let c = F::H1 as f32;  //~ ERROR casting
     assert_eq!(a, -1.0f32);
     assert_eq!(c, -1.0f32);
 }
diff --git a/src/test/compile-fail/enum-to-float-cast.rs b/src/test/compile-fail/enum-to-float-cast.rs
index 225b8702302..b562ba0e41a 100644
--- a/src/test/compile-fail/enum-to-float-cast.rs
+++ b/src/test/compile-fail/enum-to-float-cast.rs
@@ -20,8 +20,8 @@ enum F {
     H1 = 0xFFFFFFFFFFFFFFFF
 }
 
-static C0: f32 = E::L0 as f32; //~ ERROR illegal cast
-static C1: f32 = F::H1 as f32; //~ ERROR illegal cast
+static C0: f32 = E::L0 as f32; //~ ERROR casting
+static C1: f32 = F::H1 as f32; //~ ERROR casting
 
 pub fn main() {
     let b = C0;
diff --git a/src/test/compile-fail/fat-ptr-cast.rs b/src/test/compile-fail/fat-ptr-cast.rs
index 25cab09b7cb..3746f29ea55 100644
--- a/src/test/compile-fail/fat-ptr-cast.rs
+++ b/src/test/compile-fail/fat-ptr-cast.rs
@@ -17,14 +17,16 @@ fn main() {
     let p = a as *const [i32];
     let q = a.as_ptr();
 
-    a as usize; //~ ERROR illegal cast
+    a as usize; //~ ERROR casting
     b as usize; //~ ERROR non-scalar cast
-    p as usize; //~ ERROR illegal cast; cast through a raw pointer
+    p as usize;
+    //~^ ERROR casting
+    //~^^ HELP cast through a raw pointer
 
     // #22955
-    q as *const [i32]; //~ ERROR illegal cast
+    q as *const [i32]; //~ ERROR casting
 
     // #21397
-    let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR illegal cast
-    let mut fail: *const str = 0 as *const str; //~ ERROR illegal cast
+    let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting
+    let mut fail: *const str = 0 as *const str; //~ ERROR casting
 }
diff --git a/src/test/compile-fail/feature-gate-assoc-type-defaults.rs b/src/test/compile-fail/feature-gate-assoc-type-defaults.rs
new file mode 100644
index 00000000000..fc4871a712d
--- /dev/null
+++ b/src/test/compile-fail/feature-gate-assoc-type-defaults.rs
@@ -0,0 +1,15 @@
+// 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.
+
+trait Foo {
+    type Bar = u8; //~ ERROR associated type defaults are unstable
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/infinite-tag-type-recursion.rs b/src/test/compile-fail/infinite-tag-type-recursion.rs
index a57c015d684..7dbf75feda0 100644
--- a/src/test/compile-fail/infinite-tag-type-recursion.rs
+++ b/src/test/compile-fail/infinite-tag-type-recursion.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-// error-pattern: illegal recursive enum type; wrap the inner value in a box
+// error-pattern: invalid recursive enum type
 
 enum mlist { cons(isize, mlist), nil, }
 
diff --git a/src/test/compile-fail/issue-13407.rs b/src/test/compile-fail/issue-13407.rs
index f845eba4060..311280bd497 100644
--- a/src/test/compile-fail/issue-13407.rs
+++ b/src/test/compile-fail/issue-13407.rs
@@ -14,6 +14,6 @@ mod A {
 
 fn main() {
     A::C = 1;
-    //~^ ERROR: illegal left-hand side expression
+    //~^ ERROR: invalid left-hand side expression
     //~| ERROR: mismatched types
 }
diff --git a/src/test/compile-fail/issue-14845.rs b/src/test/compile-fail/issue-14845.rs
index 219f08ad35a..74f0833e8d1 100644
--- a/src/test/compile-fail/issue-14845.rs
+++ b/src/test/compile-fail/issue-14845.rs
@@ -15,8 +15,8 @@ struct X {
 
 fn main() {
     let x = X { a: [0] };
-    let _f = &x.a as *mut u8; //~ ERROR illegal cast
+    let _f = &x.a as *mut u8; //~ ERROR casting
 
     let local: [u8; 1] = [0];
-    let _v = &local as *mut u8; //~ ERROR illegal cast
+    let _v = &local as *mut u8; //~ ERROR casting
 }
diff --git a/src/test/compile-fail/issue-17431-1.rs b/src/test/compile-fail/issue-17431-1.rs
index 896a9c06873..bd3f2835058 100644
--- a/src/test/compile-fail/issue-17431-1.rs
+++ b/src/test/compile-fail/issue-17431-1.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct Foo { foo: Option<Option<Foo>> }
-//~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive struct type
 
 impl Foo { fn bar(&self) {} }
 
diff --git a/src/test/compile-fail/issue-17431-2.rs b/src/test/compile-fail/issue-17431-2.rs
index 886fe8d771a..4e1c0d6571d 100644
--- a/src/test/compile-fail/issue-17431-2.rs
+++ b/src/test/compile-fail/issue-17431-2.rs
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 struct Baz { q: Option<Foo> }
-//~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive struct type
 
 struct Foo { q: Option<Baz> }
-//~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive struct type
 
 impl Foo { fn bar(&self) {} }
 
diff --git a/src/test/compile-fail/issue-17431-3.rs b/src/test/compile-fail/issue-17431-3.rs
index c1c450935f6..07c5f106456 100644
--- a/src/test/compile-fail/issue-17431-3.rs
+++ b/src/test/compile-fail/issue-17431-3.rs
@@ -11,7 +11,7 @@
 use std::sync::Mutex;
 
 struct Foo { foo: Mutex<Option<Foo>> }
-//~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive struct type
 
 impl Foo { fn bar(&self) {} }
 
diff --git a/src/test/compile-fail/issue-17431-4.rs b/src/test/compile-fail/issue-17431-4.rs
index 22aaa796ad0..74952d9ca2b 100644
--- a/src/test/compile-fail/issue-17431-4.rs
+++ b/src/test/compile-fail/issue-17431-4.rs
@@ -11,7 +11,7 @@
 use std::marker;
 
 struct Foo<T> { foo: Option<Option<Foo<T>>>, marker: marker::PhantomData<T> }
-//~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive struct type
 
 impl<T> Foo<T> { fn bar(&self) {} }
 
diff --git a/src/test/compile-fail/issue-17431-5.rs b/src/test/compile-fail/issue-17431-5.rs
index cc9cc2e3c03..157b5ed434e 100644
--- a/src/test/compile-fail/issue-17431-5.rs
+++ b/src/test/compile-fail/issue-17431-5.rs
@@ -12,7 +12,7 @@ use std::marker;
 
 struct Foo { foo: Bar<Foo> }
 struct Bar<T> { x: Bar<Foo> , marker: marker::PhantomData<T> }
-//~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive struct type
 
 impl Foo { fn foo(&self) {} }
 
diff --git a/src/test/compile-fail/issue-17431-6.rs b/src/test/compile-fail/issue-17431-6.rs
index 8eac295353d..b2037378d37 100644
--- a/src/test/compile-fail/issue-17431-6.rs
+++ b/src/test/compile-fail/issue-17431-6.rs
@@ -11,7 +11,7 @@
 use std::sync::Mutex;
 
 enum Foo { X(Mutex<Option<Foo>>) }
-//~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive enum type
 
 impl Foo { fn bar(self) {} }
 
diff --git a/src/test/compile-fail/issue-17431-7.rs b/src/test/compile-fail/issue-17431-7.rs
index c64c040aa44..9ad81e030aa 100644
--- a/src/test/compile-fail/issue-17431-7.rs
+++ b/src/test/compile-fail/issue-17431-7.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 enum Foo { Voo(Option<Option<Foo>>) }
-//~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive enum type
 
 impl Foo { fn bar(&self) {} }
 
diff --git a/src/test/compile-fail/issue-17444.rs b/src/test/compile-fail/issue-17444.rs
index a079161d42e..c1d5827eb90 100644
--- a/src/test/compile-fail/issue-17444.rs
+++ b/src/test/compile-fail/issue-17444.rs
@@ -14,5 +14,6 @@ enum Test {
 
 fn main() {
     let _x = Test::Foo as *const isize;
-    //~^ ERROR illegal cast; cast through a usize first: `Test` as `*const isize`
+    //~^ ERROR casting `Test` as `*const isize` is invalid
+    //~^^ HELP cast through a usize first
 }
diff --git a/src/test/compile-fail/issue-21554.rs b/src/test/compile-fail/issue-21554.rs
index 16ce84715b1..741707a47b6 100644
--- a/src/test/compile-fail/issue-21554.rs
+++ b/src/test/compile-fail/issue-21554.rs
@@ -11,5 +11,7 @@
 struct Inches(i32);
 
 fn main() {
-    Inches as f32; //~ ERROR illegal cast; cast through a usize first
+    Inches as f32;
+    //~^ ERROR casting
+    //~^^ cast through a usize first
 }
diff --git a/src/test/compile-fail/issue-23073.rs b/src/test/compile-fail/issue-23073.rs
index 1286ba873be..2d219177a80 100644
--- a/src/test/compile-fail/issue-23073.rs
+++ b/src/test/compile-fail/issue-23073.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_type_defaults)]
+
 trait Foo { type T; }
 trait Bar {
     type Foo: Foo;
diff --git a/src/test/compile-fail/issue-23595-1.rs b/src/test/compile-fail/issue-23595-1.rs
index 749b261e387..a3422d859c6 100644
--- a/src/test/compile-fail/issue-23595-1.rs
+++ b/src/test/compile-fail/issue-23595-1.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_type_defaults)]
+
 use std::ops::{Index};
 
 trait Hierarchy {
diff --git a/src/test/compile-fail/issue-23595-2.rs b/src/test/compile-fail/issue-23595-2.rs
index 78a3f42f1a6..6a3ce03fce5 100644
--- a/src/test/compile-fail/issue-23595-2.rs
+++ b/src/test/compile-fail/issue-23595-2.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_type_defaults)]
+
 pub struct C<AType: A> {a:AType}
 
 pub trait A {
diff --git a/src/test/compile-fail/issue-27033.rs b/src/test/compile-fail/issue-27033.rs
new file mode 100644
index 00000000000..051edfe5f45
--- /dev/null
+++ b/src/test/compile-fail/issue-27033.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.
+
+fn main() {
+    match Some(1) {
+        None @ _ => {} //~ ERROR declaration of `None` shadows an enum variant
+    };
+    const C: u8 = 1;
+    match 1 {
+        C @ 2 => { //~ ERROR only irrefutable patterns allowed here
+            println!("{}", C);
+        }
+        _ => {}
+    };
+}
diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs
index 3ba8dd4fefe..37daf76c0b9 100644
--- a/src/test/compile-fail/issue-2718-a.rs
+++ b/src/test/compile-fail/issue-2718-a.rs
@@ -16,7 +16,7 @@ mod pingpong {
     use send_packet;
     pub type ping = send_packet<pong>;
     pub struct pong(send_packet<ping>);
-    //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+    //~^ ERROR invalid recursive struct type
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-3008-1.rs b/src/test/compile-fail/issue-3008-1.rs
index d2d7d800470..eb684208326 100644
--- a/src/test/compile-fail/issue-3008-1.rs
+++ b/src/test/compile-fail/issue-3008-1.rs
@@ -10,7 +10,7 @@
 
 enum foo { foo_(bar) }
 enum bar { bar_none, bar_some(bar) }
-//~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive enum type
 
 fn main() {
 }
diff --git a/src/test/compile-fail/issue-3008-2.rs b/src/test/compile-fail/issue-3008-2.rs
index 2f1fa6780ab..f934e0771c2 100644
--- a/src/test/compile-fail/issue-3008-2.rs
+++ b/src/test/compile-fail/issue-3008-2.rs
@@ -12,7 +12,7 @@
 
 enum foo { foo_(bar) }
 struct bar { x: bar }
-//~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive struct type
 
 fn main() {
 }
diff --git a/src/test/compile-fail/issue-3008-3.rs b/src/test/compile-fail/issue-3008-3.rs
index af6cee1f107..f8756b83f23 100644
--- a/src/test/compile-fail/issue-3008-3.rs
+++ b/src/test/compile-fail/issue-3008-3.rs
@@ -12,7 +12,7 @@ use std::marker;
 
 enum E1 { V1(E2<E1>), }
 enum E2<T> { V2(E2<E1>, marker::PhantomData<T>), }
-//~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
+//~^ ERROR invalid recursive enum type
 
 impl E1 { fn foo(&self) {} }
 
diff --git a/src/test/compile-fail/issue-3779.rs b/src/test/compile-fail/issue-3779.rs
index 19a7ed05bf4..66d8fb40cd1 100644
--- a/src/test/compile-fail/issue-3779.rs
+++ b/src/test/compile-fail/issue-3779.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct S {
-    //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
+    //~^ ERROR invalid recursive struct type
     element: Option<S>
 }
 
diff --git a/src/test/compile-fail/issue-6702.rs b/src/test/compile-fail/issue-6702.rs
index bfda113ae8b..66ed817ffa8 100644
--- a/src/test/compile-fail/issue-6702.rs
+++ b/src/test/compile-fail/issue-6702.rs
@@ -14,6 +14,6 @@ struct Monster {
 
 
 fn main() {
-    let _m = Monster(); //~ ERROR `Monster` is a struct variant name, but
+    let _m = Monster(); //~ ERROR `Monster` is the name of a struct or
     //~^ HELP did you mean to write: `Monster { /* fields */ }`?
 }
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 04db6c8c8f3..c98d7083743 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -12,6 +12,7 @@
 // injected intrinsics by the compiler.
 #![deny(missing_docs)]
 #![allow(dead_code)]
+#![feature(associated_type_defaults)]
 
 //! Some garbage docs for the crate here
 #![doc="More garbage"]
diff --git a/src/test/compile-fail/lint-unconditional-recursion.rs b/src/test/compile-fail/lint-unconditional-recursion.rs
index 47bb7f948a7..6e3a00746f3 100644
--- a/src/test/compile-fail/lint-unconditional-recursion.rs
+++ b/src/test/compile-fail/lint-unconditional-recursion.rs
@@ -41,6 +41,7 @@ fn quz() -> bool { //~ ERROR function cannot return without recurring
     }
 }
 
+// Trait method calls.
 trait Foo {
     fn bar(&self) { //~ ERROR function cannot return without recurring
         self.bar() //~ NOTE recursive call site
@@ -53,14 +54,79 @@ impl Foo for Box<Foo+'static> {
             self.bar() //~ NOTE recursive call site
         }
     }
+}
+
+// Trait method call with integer fallback after method resolution.
+impl Foo for i32 {
+    fn bar(&self) { //~ ERROR function cannot return without recurring
+        0.bar() //~ NOTE recursive call site
+    }
+}
+
+impl Foo for u32 {
+    fn bar(&self) {
+        0.bar()
+    }
+}
 
+// Trait method calls via paths.
+trait Foo2 {
+    fn bar(&self) { //~ ERROR function cannot return without recurring
+        Foo2::bar(self) //~ NOTE recursive call site
+    }
+}
+
+impl Foo2 for Box<Foo2+'static> {
+    fn bar(&self) { //~ ERROR function cannot return without recurring
+        loop {
+            Foo2::bar(self) //~ NOTE recursive call site
+        }
+    }
 }
 
 struct Baz;
 impl Baz {
+    // Inherent method call.
     fn qux(&self) { //~ ERROR function cannot return without recurring
         self.qux(); //~ NOTE recursive call site
     }
+
+    // Inherent method call via path.
+    fn as_ref(&self) -> &Self { //~ ERROR function cannot return without recurring
+        Baz::as_ref(self) //~ NOTE recursive call site
+    }
+}
+
+// Trait method calls to impls via paths.
+impl Default for Baz {
+    fn default() -> Baz { //~ ERROR function cannot return without recurring
+        let x = Default::default(); //~ NOTE recursive call site
+        x
+    }
+}
+
+// Overloaded operators.
+impl std::ops::Deref for Baz {
+    type Target = ();
+    fn deref(&self) -> &() { //~ ERROR function cannot return without recurring
+        &**self //~ NOTE recursive call site
+    }
+}
+
+impl std::ops::Index<usize> for Baz {
+    type Output = Baz;
+    fn index(&self, x: usize) -> &Baz { //~ ERROR function cannot return without recurring
+        &self[x] //~ NOTE recursive call site
+    }
+}
+
+// Overloaded autoderef.
+struct Quux;
+impl std::ops::Deref for Quux {
+    type Target = Baz;
+    fn deref(&self) -> &Baz { //~ ERROR function cannot return without recurring
+        self.as_ref() //~ NOTE recursive call site
+    }
 }
 
 fn all_fine() {
diff --git a/src/test/compile-fail/no_owned_box_lang_item.rs b/src/test/compile-fail/no_owned_box_lang_item.rs
index 49b5b5519d8..b2536701375 100644
--- a/src/test/compile-fail/no_owned_box_lang_item.rs
+++ b/src/test/compile-fail/no_owned_box_lang_item.rs
@@ -23,4 +23,5 @@ fn main() {
 
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
diff --git a/src/test/compile-fail/old-suffixes-are-really-forbidden.rs b/src/test/compile-fail/old-suffixes-are-really-forbidden.rs
index b18741d3932..9a71dc98014 100644
--- a/src/test/compile-fail/old-suffixes-are-really-forbidden.rs
+++ b/src/test/compile-fail/old-suffixes-are-really-forbidden.rs
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 fn main() {
-    let a = 1_is; //~ ERROR illegal suffix
-    let b = 2_us; //~ ERROR illegal suffix
+    let a = 1_is; //~ ERROR invalid suffix
+    let b = 2_us; //~ ERROR invalid suffix
 }
diff --git a/src/test/compile-fail/recursive-enum.rs b/src/test/compile-fail/recursive-enum.rs
index 119f6dae9e5..33dcbdf74d2 100644
--- a/src/test/compile-fail/recursive-enum.rs
+++ b/src/test/compile-fail/recursive-enum.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: illegal recursive enum type
+// error-pattern: invalid recursive enum type
 
 enum list<T> { cons(T, list<T>), nil }
 
diff --git a/src/test/compile-fail/regions-name-static.rs b/src/test/compile-fail/regions-name-static.rs
index 29896aa486b..69d63f3820c 100644
--- a/src/test/compile-fail/regions-name-static.rs
+++ b/src/test/compile-fail/regions-name-static.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<'static> { //~ ERROR illegal lifetime parameter name: `'static`
+struct Foo<'static> { //~ ERROR invalid lifetime parameter name: `'static`
     x: &'static isize
 }
 
diff --git a/src/test/compile-fail/type-recursive.rs b/src/test/compile-fail/type-recursive.rs
index b972934d060..3b08d900733 100644
--- a/src/test/compile-fail/type-recursive.rs
+++ b/src/test/compile-fail/type-recursive.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:illegal recursive struct type
+// error-pattern:invalid recursive struct type
 struct t1 {
     foo: isize,
     foolish: t1
diff --git a/src/test/compile-fail/typeck-cast-pointer-to-float.rs b/src/test/compile-fail/typeck-cast-pointer-to-float.rs
index e10a76c65bc..2277b1bad77 100644
--- a/src/test/compile-fail/typeck-cast-pointer-to-float.rs
+++ b/src/test/compile-fail/typeck-cast-pointer-to-float.rs
@@ -11,5 +11,6 @@
 fn main() {
     let x : i16 = 22;
     ((&x) as *const i16) as f32;
-    //~^ ERROR illegal cast; cast through a usize first: `*const i16` as `f32`
+    //~^ ERROR casting `*const i16` as `f32` is invalid
+    //~^^ HELP cast through a usize first
 }
diff --git a/src/test/compile-fail/unboxed-closure-feature-gate.rs b/src/test/compile-fail/unboxed-closure-feature-gate.rs
index 74a6f869f63..3a3ea058b4e 100644
--- a/src/test/compile-fail/unboxed-closure-feature-gate.rs
+++ b/src/test/compile-fail/unboxed-closure-feature-gate.rs
@@ -21,7 +21,7 @@ trait Foo<A> {
 
 fn main() {
     let x: Box<Foo(isize)>;
-    //~^ ERROR parenthetical notation is only stable when used with the `Fn` family
+    //~^ ERROR parenthetical notation is only stable when used with `Fn`-family
 
     // No errors with these:
     let x: Box<Fn(isize)>;
diff --git a/src/test/compile-fail/unboxed-closure-sugar-not-used-on-fn.rs b/src/test/compile-fail/unboxed-closure-sugar-not-used-on-fn.rs
index 5a821ef1231..ed27a4d0b2a 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-not-used-on-fn.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-not-used-on-fn.rs
@@ -12,11 +12,11 @@
 // Test that the `Fn` traits require `()` form without a feature gate.
 
 fn bar1(x: &Fn<(), Output=()>) {
-    //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family
+    //~^ ERROR of `Fn`-family traits' type parameters is subject to change
 }
 
 fn bar2<T>(x: &T) where T: Fn<()> {
-    //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family
+    //~^ ERROR of `Fn`-family traits' type parameters is subject to change
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/unsupported-cast.rs b/src/test/compile-fail/unsupported-cast.rs
index b4246f2ed87..8b63dd51729 100644
--- a/src/test/compile-fail/unsupported-cast.rs
+++ b/src/test/compile-fail/unsupported-cast.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:illegal cast
+// error-pattern:casting
 
 #![feature(libc)]
 
diff --git a/src/test/compile-fail/vector-cast-weirdness.rs b/src/test/compile-fail/vector-cast-weirdness.rs
index 10227f1820d..26c59c440d4 100644
--- a/src/test/compile-fail/vector-cast-weirdness.rs
+++ b/src/test/compile-fail/vector-cast-weirdness.rs
@@ -28,7 +28,7 @@ fn main() {
     let mut x1 = X { y: [0, 0] };
 
     // This is still an error since we don't allow casts from &mut [T; n] to *mut T.
-    let p1: *mut u8 = &mut x1.y as *mut _;  //~ ERROR illegal cast
+    let p1: *mut u8 = &mut x1.y as *mut _;  //~ ERROR casting
     let t1: *mut [u8; 2] = &mut x1.y as *mut _;
     let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2];
 }
diff --git a/src/test/debuginfo/basic-types-metadata.rs b/src/test/debuginfo/basic-types-metadata.rs
index 2468150a6a5..3b662ae0264 100644
--- a/src/test/debuginfo/basic-types-metadata.rs
+++ b/src/test/debuginfo/basic-types-metadata.rs
@@ -46,6 +46,21 @@
 // gdb-check:type = [...] (*)([...])
 // gdb-command:info functions _yyy
 // gdb-check:[...]![...]_yyy([...]);
+// gdb-command:ptype closure_0
+// gdb-check: type = struct closure {
+// gdb-check:     <no data fields>
+// gdb-check: }
+// gdb-command:ptype closure_1
+// gdb-check: type = struct closure {
+// gdb-check:     bool *__0;
+// gdb-check: }
+// gdb-command:ptype closure_2
+// gdb-check: type = struct closure {
+// gdb-check:     bool *__0;
+// gdb-check:     isize *__1;
+// gdb-check: }
+
+//
 // gdb-command:continue
 
 #![allow(unused_variables)]
@@ -68,6 +83,9 @@ fn main() {
     let f32: f32 = 2.5;
     let f64: f64 = 3.5;
     let fnptr : fn() = _zzz;
+    let closure_0 = || {};
+    let closure_1 = || { b; };
+    let closure_2 = || { if b { i } else { i }; };
     _zzz(); // #break
     if 1 == 1 { _yyy(); }
 }
diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
new file mode 100644
index 00000000000..56a973fa59f
--- /dev/null
+++ b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs
@@ -0,0 +1,188 @@
+// 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-windows failing on win32 bot
+// ignore-freebsd: output doesn't match
+// ignore-tidy-linelength
+// ignore-lldb
+// ignore-android: FIXME(#10381)
+// compile-flags:-g
+
+// This test uses some GDB Python API features (e.g. accessing anonymous fields)
+// which are only available in newer GDB version. The following directive will
+// case the test runner to ignore this test if an older GDB version is used:
+// min-gdb-version 7.7
+
+// gdb-command: run
+
+// gdb-command: print regular_struct
+// gdb-check:$1 = RegularStruct = {the_first_field = 101, the_second_field = 102.5, the_third_field = false, the_fourth_field = "I'm so pretty, oh so pretty..."}
+
+// gdb-command: print tuple
+// gdb-check:$2 = {true, 103, "blub"}
+
+// gdb-command: print tuple_struct
+// gdb-check:$3 = TupleStruct = {-104.5, 105}
+
+// gdb-command: print empty_struct
+// gdb-check:$4 = EmptyStruct
+
+// gdb-command: print c_style_enum1
+// gdb-check:$5 = CStyleEnumVar1
+
+// gdb-command: print c_style_enum2
+// gdb-check:$6 = CStyleEnumVar2
+
+// gdb-command: print c_style_enum3
+// gdb-check:$7 = CStyleEnumVar3
+
+// gdb-command: print mixed_enum_c_style_var
+// gdb-check:$8 = MixedEnumCStyleVar
+
+// gdb-command: print mixed_enum_tuple_var
+// gdb-check:$9 = MixedEnumTupleVar = {106, 107, false}
+
+// gdb-command: print mixed_enum_struct_var
+// gdb-check:$10 = MixedEnumStructVar = {field1 = 108.5, field2 = 109}
+
+// gdb-command: print some
+// gdb-check:$11 = Some = {110}
+
+// gdb-command: print none
+// gdb-check:$12 = None
+
+// gdb-command: print some_fat
+// gdb-check:$13 = Some = {"abc"}
+
+// gdb-command: print none_fat
+// gdb-check:$14 = None
+
+// gdb-command: print nested_variant1
+// gdb-check:$15 = NestedVariant1 = {NestedStruct = {regular_struct = RegularStruct = {the_first_field = 111, the_second_field = 112.5, the_third_field = true, the_fourth_field = "NestedStructString1"}, tuple_struct = TupleStruct = {113.5, 114}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar2, mixed_enum = MixedEnumTupleVar = {115, 116, false}}}
+
+// gdb-command: print nested_variant2
+// gdb-check:$16 = NestedVariant2 = {abc = NestedStruct = {regular_struct = RegularStruct = {the_first_field = 117, the_second_field = 118.5, the_third_field = false, the_fourth_field = "NestedStructString10"}, tuple_struct = TupleStruct = {119.5, 120}, empty_struct = EmptyStruct, c_style_enum = CStyleEnumVar3, mixed_enum = MixedEnumStructVar = {field1 = 121.5, field2 = -122}}}
+
+// gdb-command: print none_check1
+// gdb-check:$17 = None
+
+// gdb-command: print none_check2
+// gdb-check:$18 = None
+
+#![allow(dead_code, unused_variables)]
+
+use self::CStyleEnum::{CStyleEnumVar1, CStyleEnumVar2, CStyleEnumVar3};
+use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar};
+use self::NestedEnum::{NestedVariant1, NestedVariant2};
+
+struct RegularStruct {
+    the_first_field: isize,
+    the_second_field: f64,
+    the_third_field: bool,
+    the_fourth_field: &'static str,
+}
+
+struct TupleStruct(f64, i16);
+
+struct EmptyStruct;
+
+enum CStyleEnum {
+    CStyleEnumVar1,
+    CStyleEnumVar2,
+    CStyleEnumVar3,
+}
+
+enum MixedEnum {
+    MixedEnumCStyleVar,
+    MixedEnumTupleVar(u32, u16, bool),
+    MixedEnumStructVar { field1: f64, field2: i32 }
+}
+
+struct NestedStruct {
+    regular_struct: RegularStruct,
+    tuple_struct: TupleStruct,
+    empty_struct: EmptyStruct,
+    c_style_enum: CStyleEnum,
+    mixed_enum: MixedEnum,
+}
+
+enum NestedEnum {
+    NestedVariant1(NestedStruct),
+    NestedVariant2 { abc: NestedStruct }
+}
+
+fn main() {
+
+    let regular_struct = RegularStruct {
+        the_first_field: 101,
+        the_second_field: 102.5,
+        the_third_field: false,
+        the_fourth_field: "I'm so pretty, oh so pretty..."
+    };
+
+    let tuple = ( true, 103u32, "blub" );
+
+    let tuple_struct = TupleStruct(-104.5, 105);
+
+    let empty_struct = EmptyStruct;
+
+    let c_style_enum1 = CStyleEnumVar1;
+    let c_style_enum2 = CStyleEnumVar2;
+    let c_style_enum3 = CStyleEnumVar3;
+
+    let mixed_enum_c_style_var = MixedEnumCStyleVar;
+    let mixed_enum_tuple_var = MixedEnumTupleVar(106, 107, false);
+    let mixed_enum_struct_var = MixedEnumStructVar { field1: 108.5, field2: 109 };
+
+    let some = Some(110_usize);
+    let none: Option<isize> = None;
+    let some_fat = Some("abc");
+    let none_fat: Option<&'static str> = None;
+
+    let nested_variant1 = NestedVariant1(
+        NestedStruct {
+            regular_struct: RegularStruct {
+                the_first_field: 111,
+                the_second_field: 112.5,
+                the_third_field: true,
+                the_fourth_field: "NestedStructString1",
+            },
+            tuple_struct: TupleStruct(113.5, 114),
+            empty_struct: EmptyStruct,
+            c_style_enum: CStyleEnumVar2,
+            mixed_enum: MixedEnumTupleVar(115, 116, false)
+        }
+    );
+
+    let nested_variant2 = NestedVariant2 {
+        abc: NestedStruct {
+            regular_struct: RegularStruct {
+                the_first_field: 117,
+                the_second_field: 118.5,
+                the_third_field: false,
+                the_fourth_field: "NestedStructString10",
+            },
+            tuple_struct: TupleStruct(119.5, 120),
+            empty_struct: EmptyStruct,
+            c_style_enum: CStyleEnumVar3,
+            mixed_enum: MixedEnumStructVar {
+                field1: 121.5,
+                field2: -122
+            }
+        }
+    };
+
+    let none_check1: Option<(usize, Vec<usize>)> = None;
+    let none_check2: Option<String> = None;
+
+    zzz(); // #break
+}
+
+fn zzz() { () }
diff --git a/src/test/parse-fail/bad-lit-suffixes.rs b/src/test/parse-fail/bad-lit-suffixes.rs
index a64ee6a9ce2..a2ee2f6e88c 100644
--- a/src/test/parse-fail/bad-lit-suffixes.rs
+++ b/src/test/parse-fail/bad-lit-suffixes.rs
@@ -12,28 +12,28 @@
 
 
 extern
-    "C"suffix //~ ERROR ABI spec with a suffix is illegal
+    "C"suffix //~ ERROR ABI spec with a suffix is invalid
     fn foo() {}
 
 extern
-    "C"suffix //~ ERROR ABI spec with a suffix is illegal
+    "C"suffix //~ ERROR ABI spec with a suffix is invalid
 {}
 
 fn main() {
-    ""suffix; //~ ERROR str literal with a suffix is illegal
-    b""suffix; //~ ERROR binary str literal with a suffix is illegal
-    r#""#suffix; //~ ERROR str literal with a suffix is illegal
-    br#""#suffix; //~ ERROR binary str literal with a suffix is illegal
-    'a'suffix; //~ ERROR char literal with a suffix is illegal
-    b'a'suffix; //~ ERROR byte literal with a suffix is illegal
+    ""suffix; //~ ERROR str literal with a suffix is invalid
+    b""suffix; //~ ERROR binary str literal with a suffix is invalid
+    r#""#suffix; //~ ERROR str literal with a suffix is invalid
+    br#""#suffix; //~ ERROR binary str literal with a suffix is invalid
+    'a'suffix; //~ ERROR char literal with a suffix is invalid
+    b'a'suffix; //~ ERROR byte literal with a suffix is invalid
 
-    1234u1024; //~ ERROR illegal width `1024` for integer literal
-    1234i1024; //~ ERROR illegal width `1024` for integer literal
-    1234f1024; //~ ERROR illegal width `1024` for float literal
-    1234.5f1024; //~ ERROR illegal width `1024` for float literal
+    1234u1024; //~ ERROR invalid width `1024` for integer literal
+    1234i1024; //~ ERROR invalid width `1024` for integer literal
+    1234f1024; //~ ERROR invalid width `1024` for float literal
+    1234.5f1024; //~ ERROR invalid width `1024` for float literal
 
-    1234suffix; //~ ERROR illegal suffix `suffix` for numeric literal
-    0b101suffix; //~ ERROR illegal suffix `suffix` for numeric literal
-    1.0suffix; //~ ERROR illegal suffix `suffix` for float literal
-    1.0e10suffix; //~ ERROR illegal suffix `suffix` for float literal
+    1234suffix; //~ ERROR invalid suffix `suffix` for numeric literal
+    0b101suffix; //~ ERROR invalid suffix `suffix` for numeric literal
+    1.0suffix; //~ ERROR invalid suffix `suffix` for float literal
+    1.0e10suffix; //~ ERROR invalid suffix `suffix` for float literal
 }
diff --git a/src/test/parse-fail/byte-literals.rs b/src/test/parse-fail/byte-literals.rs
index 6685a29bb42..3321f2450c1 100644
--- a/src/test/parse-fail/byte-literals.rs
+++ b/src/test/parse-fail/byte-literals.rs
@@ -17,7 +17,7 @@ static FOO: u8 = b'\f';  //~ ERROR unknown byte escape
 
 pub fn main() {
     b'\f';  //~ ERROR unknown byte escape
-    b'\x0Z';  //~ ERROR illegal character in numeric character escape: Z
+    b'\x0Z';  //~ ERROR invalid character in numeric character escape: Z
     b'	';  //~ ERROR byte constant must be escaped
     b''';  //~ ERROR byte constant must be escaped
     b'é';  //~ ERROR byte constant must be ASCII
diff --git a/src/test/parse-fail/byte-string-literals.rs b/src/test/parse-fail/byte-string-literals.rs
index 7049363c21b..22f123416f2 100644
--- a/src/test/parse-fail/byte-string-literals.rs
+++ b/src/test/parse-fail/byte-string-literals.rs
@@ -17,7 +17,7 @@ static FOO: &'static [u8] = b"\f";  //~ ERROR unknown byte escape
 
 pub fn main() {
     b"\f";  //~ ERROR unknown byte escape
-    b"\x0Z";  //~ ERROR illegal character in numeric character escape: Z
+    b"\x0Z";  //~ ERROR invalid character in numeric character escape: Z
     b"é";  //~ ERROR byte constant must be ASCII
     b"a  //~ ERROR unterminated double quote byte string
 }
diff --git a/src/test/parse-fail/empty-impl-semicolon.rs b/src/test/parse-fail/empty-impl-semicolon.rs
index e356ab1debc..d9f8add8cfb 100644
--- a/src/test/parse-fail/empty-impl-semicolon.rs
+++ b/src/test/parse-fail/empty-impl-semicolon.rs
@@ -10,4 +10,4 @@
 
 // compile-flags: -Z parse-only
 
-impl Foo; //~ ERROR expected one of `(`, `+`, `..`, `::`, `<`, `for`, `where`, or `{`, found `;`
+impl Foo; //~ ERROR expected one of `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;`
diff --git a/src/test/parse-fail/issue-23620-invalid-escapes.rs b/src/test/parse-fail/issue-23620-invalid-escapes.rs
index 1790b9164b7..d2f78ef897b 100644
--- a/src/test/parse-fail/issue-23620-invalid-escapes.rs
+++ b/src/test/parse-fail/issue-23620-invalid-escapes.rs
@@ -23,25 +23,25 @@ fn main() {
     //~^ ERROR numeric character escape is too short
 
     let _ = b'\xxy';
-    //~^ ERROR illegal character in numeric character escape: x
-    //~^^ ERROR illegal character in numeric character escape: y
+    //~^ ERROR invalid character in numeric character escape: x
+    //~^^ ERROR invalid character in numeric character escape: y
 
     let _ = '\x5';
     //~^ ERROR numeric character escape is too short
 
     let _ = '\xxy';
-    //~^ ERROR illegal character in numeric character escape: x
-    //~^^ ERROR illegal character in numeric character escape: y
+    //~^ ERROR invalid character in numeric character escape: x
+    //~^^ ERROR invalid character in numeric character escape: y
 
     let _ = b"\u{a4a4} \xf \u";
     //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
-    //~^^ ERROR illegal character in numeric character escape:
+    //~^^ ERROR invalid character in numeric character escape:
     //~^^^ ERROR incorrect unicode escape sequence
     //~^^^^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
 
     let _ = "\u{ffffff} \xf \u";
-    //~^ ERROR illegal unicode character escape
-    //~^^ ERROR illegal character in numeric character escape:
+    //~^ ERROR invalid unicode character escape
+    //~^^ ERROR invalid character in numeric character escape:
     //~^^^ ERROR form of character escape may only be used with characters in the range [\x00-\x7f]
     //~^^^^ ERROR incorrect unicode escape sequence
 }
diff --git a/src/test/parse-fail/issue-27255.rs b/src/test/parse-fail/issue-27255.rs
new file mode 100644
index 00000000000..a751c4af494
--- /dev/null
+++ b/src/test/parse-fail/issue-27255.rs
@@ -0,0 +1,15 @@
+// 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.
+
+// compile-flags: -Z parse-only
+
+impl A .. {} //~ ERROR
+
+fn main() {}
diff --git a/src/test/parse-fail/issue-8537.rs b/src/test/parse-fail/issue-8537.rs
index 5996b744566..e152a369290 100644
--- a/src/test/parse-fail/issue-8537.rs
+++ b/src/test/parse-fail/issue-8537.rs
@@ -11,7 +11,7 @@
 // compile-flags: -Z parse-only
 
 pub extern
-  "invalid-ab_isize" //~ ERROR illegal ABI
+  "invalid-ab_isize" //~ ERROR invalid ABI
 fn foo() {}
 
 fn main() {}
diff --git a/src/test/parse-fail/multitrait.rs b/src/test/parse-fail/multitrait.rs
index a1c737609d1..2a8d6d99957 100644
--- a/src/test/parse-fail/multitrait.rs
+++ b/src/test/parse-fail/multitrait.rs
@@ -15,7 +15,7 @@ struct S {
 }
 
 impl Cmp, ToString for S {
-//~^ ERROR: expected one of `(`, `+`, `..`, `::`, `<`, `for`, `where`, or `{`, found `,`
+//~^ ERROR: expected one of `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,`
   fn eq(&&other: S) { false }
   fn to_string(&self) -> String { "hi".to_string() }
 }
diff --git a/src/test/parse-fail/new-unicode-escapes-3.rs b/src/test/parse-fail/new-unicode-escapes-3.rs
index 5e8bc16ac6e..d12bb63111b 100644
--- a/src/test/parse-fail/new-unicode-escapes-3.rs
+++ b/src/test/parse-fail/new-unicode-escapes-3.rs
@@ -11,5 +11,5 @@
 // compile-flags: -Z parse-only
 
 pub fn main() {
-    let s = "\u{d805}"; //~ ERROR illegal unicode character escape
+    let s = "\u{d805}"; //~ ERROR invalid unicode character escape
 }
diff --git a/src/test/parse-fail/new-unicode-escapes-4.rs b/src/test/parse-fail/new-unicode-escapes-4.rs
index 896751bd4a7..fe125da1755 100644
--- a/src/test/parse-fail/new-unicode-escapes-4.rs
+++ b/src/test/parse-fail/new-unicode-escapes-4.rs
@@ -12,7 +12,7 @@
 
 pub fn main() {
     let s = "\u{lol}";
-     //~^ ERROR illegal character in unicode escape: l
-     //~^^ ERROR illegal character in unicode escape: o
-     //~^^^ ERROR illegal character in unicode escape: l
+     //~^ ERROR invalid character in unicode escape: l
+     //~^^ ERROR invalid character in unicode escape: o
+     //~^^^ ERROR invalid character in unicode escape: l
 }
diff --git a/src/test/parse-fail/raw-str-delim.rs b/src/test/parse-fail/raw-str-delim.rs
index c7ef91f14f5..3fc5f8aae18 100644
--- a/src/test/parse-fail/raw-str-delim.rs
+++ b/src/test/parse-fail/raw-str-delim.rs
@@ -11,5 +11,5 @@
 // compile-flags: -Z parse-only
 
 static s: &'static str =
-    r#x"#"x# //~ ERROR only `#` is allowed in raw string delimitation; found illegal character
+    r#x"#"x# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation
 ;
diff --git a/src/test/parse-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs
index 7a20b00ce12..3bd8908d18b 100644
--- a/src/test/parse-fail/trait-bounds-not-on-impl.rs
+++ b/src/test/parse-fail/trait-bounds-not-on-impl.rs
@@ -17,7 +17,7 @@ struct Bar;
 
 impl Foo + Owned for Bar {
 //~^ ERROR not a trait
-//~^^ ERROR expected one of `..`, `where`, or `{`, found `Bar`
+//~^^ ERROR expected one of `where` or `{`, found `Bar`
 }
 
 fn main() { }
diff --git a/src/test/run-make/c-link-to-rust-staticlib/Makefile b/src/test/run-make/c-link-to-rust-staticlib/Makefile
index 56c09b895f1..2b927e3e4a7 100644
--- a/src/test/run-make/c-link-to-rust-staticlib/Makefile
+++ b/src/test/run-make/c-link-to-rust-staticlib/Makefile
@@ -1,8 +1,6 @@
 -include ../tools.mk
 
-ifndef IS_WINDOWS
 EXTRAFLAGS := $(EXTRACFLAGS)
-endif
 
 # FIXME: ignore freebsd
 ifneq ($(shell uname),FreeBSD)
diff --git a/src/test/run-make/graphviz-flowgraph/Makefile b/src/test/run-make/graphviz-flowgraph/Makefile
index 1533729de94..5740a36359c 100644
--- a/src/test/run-make/graphviz-flowgraph/Makefile
+++ b/src/test/run-make/graphviz-flowgraph/Makefile
@@ -28,7 +28,7 @@ $(TMPDIR)/%.pp: %.rs
 
 $(TMPDIR)/%.dot: %.rs
 	$(eval $(call FIND_LAST_BLOCK,$<))
-	$(RUSTC_LIB) -Z unstable-options --xpretty flowgraph,unlabelled=$(LASTBLOCKNUM_$<) $< -o $@.tmp
+	$(RUSTC_LIB) -Z unstable-options --unpretty flowgraph,unlabelled=$(LASTBLOCKNUM_$<) $< -o $@.tmp
 	cat $@.tmp | sed -e 's@ (id=[0-9]*)@@g' \
                          -e 's@\[label=""\]@@' \
                          -e 's@digraph [a-zA-Z0-9_]* @digraph block @' \
diff --git a/src/test/run-make/no-duplicate-libs/bar.rs b/src/test/run-make/no-duplicate-libs/bar.rs
index 29f52f97a88..2c92778f59a 100644
--- a/src/test/run-make/no-duplicate-libs/bar.rs
+++ b/src/test/run-make/no-duplicate-libs/bar.rs
@@ -19,4 +19,5 @@ pub extern fn bar() {}
 
 #[lang = "stack_exhausted"] fn stack_exhausted() {}
 #[lang = "eh_personality"] fn eh_personality() {}
+#[lang = "eh_unwind_resume"] fn eh_unwind_resume() {}
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
diff --git a/src/test/run-make/no-duplicate-libs/foo.rs b/src/test/run-make/no-duplicate-libs/foo.rs
index ae424c6569d..b3a36ec3efd 100644
--- a/src/test/run-make/no-duplicate-libs/foo.rs
+++ b/src/test/run-make/no-duplicate-libs/foo.rs
@@ -19,4 +19,6 @@ pub extern fn foo() {}
 
 #[lang = "stack_exhausted"] fn stack_exhausted() {}
 #[lang = "eh_personality"] fn eh_personality() {}
+#[lang = "eh_unwind_resume"] fn eh_unwind_resume() {}
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+
diff --git a/src/test/run-pass/default-associated-types.rs b/src/test/run-pass/default-associated-types.rs
index b3def429b9b..3e6c72c993a 100644
--- a/src/test/run-pass/default-associated-types.rs
+++ b/src/test/run-pass/default-associated-types.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_type_defaults)]
+
 trait Foo<T> {
     type Out = T;
     fn foo(&self) -> Self::Out;
diff --git a/src/test/run-pass/issue-24086.rs b/src/test/run-pass/issue-24086.rs
new file mode 100644
index 00000000000..0a8324eafe2
--- /dev/null
+++ b/src/test/run-pass/issue-24086.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.
+
+pub struct Registry<'a> {
+    listener: &'a mut (),
+}
+
+pub struct Listener<'a> {
+    pub announce: Option<Box<FnMut(&mut Registry) + 'a>>,
+    pub remove: Option<Box<FnMut(&mut Registry) + 'a>>,
+}
+
+impl<'a> Drop for Registry<'a> {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    let mut registry_listener = Listener {
+        announce: None,
+        remove: None,
+    };
+}
diff --git a/src/test/run-pass/issue-25339.rs b/src/test/run-pass/issue-25339.rs
index af172000fdb..381df7c5d59 100644
--- a/src/test/run-pass/issue-25339.rs
+++ b/src/test/run-pass/issue-25339.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_type_defaults)]
+
 use std::marker::PhantomData;
 
 pub trait Routing<I> {
diff --git a/src/test/run-pass/issue-26641.rs b/src/test/run-pass/issue-26641.rs
new file mode 100644
index 00000000000..16f1d4626fb
--- /dev/null
+++ b/src/test/run-pass/issue-26641.rs
@@ -0,0 +1,15 @@
+// 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.
+
+struct Parser<'a>(Box<FnMut(Parser) + 'a>);
+
+fn main() {
+    let _x = Parser(Box::new(|_|{}));
+}
diff --git a/src/test/run-pass/issue-27240.rs b/src/test/run-pass/issue-27240.rs
new file mode 100644
index 00000000000..4e341d31172
--- /dev/null
+++ b/src/test/run-pass/issue-27240.rs
@@ -0,0 +1,33 @@
+// 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.
+
+use std::fmt;
+struct NoisyDrop<T: fmt::Debug>(T);
+impl<T: fmt::Debug> Drop for NoisyDrop<T> {
+    fn drop(&mut self) {}
+}
+
+struct Bar<T: fmt::Debug>([*const NoisyDrop<T>; 2]);
+
+fn fine() {
+    let (u,b);
+    u = vec![43];
+    b = Bar([&NoisyDrop(&u), &NoisyDrop(&u)]);
+}
+
+struct Bar2<T: fmt::Debug>(*const NoisyDrop<T>, *const NoisyDrop<T>);
+
+fn lolwut() {
+    let (u,v);
+    u = vec![43];
+    v = Bar2(&NoisyDrop(&u), &NoisyDrop(&u));
+}
+
+fn main() { fine(); lolwut() }
diff --git a/src/test/run-pass/lint-cap.rs b/src/test/run-pass/lint-cap.rs
new file mode 100644
index 00000000000..003a99f746a
--- /dev/null
+++ b/src/test/run-pass/lint-cap.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.
+
+// compile-flags: --cap-lints allow
+
+#![deny(warnings)]
+
+use std::option;
+
+fn main() {}
+
diff --git a/src/test/run-pass/smallest-hello-world.rs b/src/test/run-pass/smallest-hello-world.rs
index 5e84ce19de1..67affb5ae09 100644
--- a/src/test/run-pass/smallest-hello-world.rs
+++ b/src/test/run-pass/smallest-hello-world.rs
@@ -22,6 +22,7 @@ extern "rust-intrinsic" { fn transmute<T, U>(t: T) -> U; }
 
 #[lang = "stack_exhausted"] extern fn stack_exhausted() {}
 #[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
 
 #[start]
diff --git a/src/test/run-pass/sync-send-atomics.rs b/src/test/run-pass/sync-send-atomics.rs
new file mode 100644
index 00000000000..1ead6268d0c
--- /dev/null
+++ b/src/test/run-pass/sync-send-atomics.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.
+
+// pretty-expanded FIXME #23616
+
+use std::sync::atomic::*;
+
+trait SendSync: Send + Sync {}
+
+impl SendSync for AtomicBool {}
+impl SendSync for AtomicIsize {}
+impl SendSync for AtomicUsize {}
+impl<T> SendSync for AtomicPtr<T> {}
+
+fn main() {}